


import time
from multiprocessing import Process,Queue
import multiprocessing
from threading import Thread
from binascii import unhexlify
 
import pymysql
import datetime

import modbus_tk.defines as cst
import modbus_tk.modbus_tcp as modbus_tcp

from math import ceil
from numpy import average
import os
from openpyxl import load_workbook

from configparser import ConfigParser
import logging
from logging import handlers

import json

def initStaStatus(staStatus,stas):
    for station in stas:
        for sta in station:
            staStatus[sta]={}
            tmp = staStatus[sta]
            tmp['EUN'] = ''
            tmp['goodpiece'] = 0
            tmp['rejectpiece'] = 0
            tmp['lastcycle'] = 0
            tmp['currentcycle'] = 0
            tmp['teamleader'] = 0
            tmp['maintenance'] = 0
            tmp['blocked'] = 0
            tmp['starved'] = 0
            tmp['bypass'] = 0
            tmp['fault'] = 0
            tmp['present'] = 0
            tmp['buildable'] = 0
            tmp['palletno'] = 0
            tmp['auto'] = 1
            tmp['other'] = 'XXX'
            staStatus[sta] = tmp

def initErrorStatus(errorStatus,errorIDs):
    for errorID in errorIDs:
        for eid in errorID:
            errorStatus[eid]=0

def initConfig():
    ips = []
    stasR = []
    stasP = []
    stasB = []
    stasPalletno = []
    errorStations = []
    errorIDs = []
    errorListVisible = []
    
    wb = load_workbook('config.xlsx')
    sheetnames = wb.sheetnames

    for sheetname in sheetnames:
        ws = wb[sheetname]
        ip = ws.cell(2,2).value
        ips.append(ip)

        erroridTemp = []
        errorstationTemp = []
        for i in range(6,50):
            if ws.cell(i,2).value == None:
                break
            else:
                erroridTemp.append(int(ws.cell(i,2).value))
                errorstationTemp.append(ws.cell(i,3).value)
                if ws.cell(i,5).value != 'ALL':
                    temp = []
                    temp = set(ws.cell(i,5).value.split(','))
                    errorListVisible.append([int(ws.cell(i,2).value) , ws.cell(i,3).value , temp])

        errorIDs.append(erroridTemp)
        errorStations.append(errorstationTemp)

        staRtemp=[]
        for i in range(6,50):
            if ws.cell(i,7).value==None:
                break
            else:
                staRtemp.append(ws.cell(i,7).value)
        stasR.append(staRtemp)

        staBtemp=[]
        for i in range(6,50):
            if ws.cell(i,10).value==None:
                break
            else:
                staBtemp.append(ws.cell(i,10).value)
        stasB.append(staBtemp)

        staPtemp=[]
        for i in range(6,50):
            if ws.cell(i,13).value==None:
                break
            else:
                staPtemp.append(ws.cell(i,13).value)
        stasP.append(staPtemp)

        staPalletnotemp=[]
        for i in range(6,50):
            if ws.cell(i,16).value==None:
                break
            else:
                staPalletnotemp.append(ws.cell(i,16).value)
        stasPalletno.append(staPalletnotemp)

    ns=[ceil(len(s)/4) for s in stasR]

    return ips,stasR,stasP,stasB,stasPalletno,errorStations,errorIDs,ns,errorListVisible


def initErrorDB():
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()
    curdate=datetime.datetime.now().strftime("%Y-%m-%d")

    sqlfun0="select * from assembly.errorproofing where errorproofing_date='%s' order by errorproofing_id desc limit 1 "%(curdate)
    cur.execute(sqlfun0)
    data=cur.fetchall()

    if len(data)==0:
        sqlfun="select * from assembly.errorproofing_default"
        cur.execute(sqlfun)
        data=cur.fetchall()

        for shift in ["白","中"]:
            for d in data:
                sqlfun1="insert into assembly.errorproofing(errorproofing_errorid,errorproofing_date,"\
                    "errorproofing_time,errorproofing_station,errorproofing_detail,errorproofing_occured,"\
                        "errorproofing_shift)values( %d,'%s','now()','%s','%s','0','%s')"%(d[1],curdate,d[4],d[5],shift)
                cur.execute(sqlfun1)

        cnx.commit()
        cur.close()
        cnx.close()
    
def shiftHourGet():
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()

    sqlfun="select shift from assembly.shift_hour order by id desc limit 1"
    cur.execute(sqlfun)
    shiftHour=cur.fetchall()[0][0]

    cnx.commit()
    cur.close()
    cnx.close()

    return shiftHour



def updateDatabase(errorID,errorEUN,errorQueue,shiftHour,append = ''):
    try:
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
        cur=cnx.cursor()
        curdatetime=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        curdate=datetime.datetime.now().strftime("%Y-%m-%d")
        curhour=int(datetime.datetime.now().strftime("%H"))
        curmin=int(datetime.datetime.now().strftime("%M"))
        
        if curhour >= 7 and curhour+curmin/60 < shiftHour[0]:
            curshift='白'
        else:
            curshift='中'

        print(curdatetime,curdate,curhour,curshift,errorID)
        
        sqlfun="UPDATE assembly.errorproofing SET errorProofing_occured = 0 ,"\
            " errorProofing_time = '%s' WHERE errorproofing_date = '%s' and "\
                "errorproofing_shift='%s' and errorproofing_errorid=%d"\
                    %(curdatetime,curdate,curshift,errorID)


        sqlfun1="insert into assembly.errorproofing_record(errorproofing_record_errorid,"\
            "errorproofing_record_eun,errorproofing_record_time,errorproofing_record_append)"\
            "values( %d,'%s','%s','%s')"\
            %(errorID,errorEUN,curdatetime,append)
##        print(sqlfun1)
        hhh = (curhour+curmin/60) - shiftHour[0]
        if curhour in [7,8] or (hhh >= 0 and hhh <= 1):
            try:
                cur.execute(sqlfun)
            except Exception as e:
                text = sqlfun + '     ' + str(e)
                errorQueue.put(['err',text])
                time.sleep(1)
                initErrorDB()
                cur.execute(sqlfun)
                
        cur.execute(sqlfun1)
        cnx.commit()
        cur.close()
        cnx.close()
        
    except BaseException as e:
        print ("Error: unable to update data. Code:",e,sqlfun,sqlfun1)
        text = 'Error: unable to update data. Code: ' + str(e)
        errorQueue.put(['err',text])

def updateErrorListVisible(errorID,shiftHour):
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()
    curdate=datetime.datetime.now().strftime("%Y-%m-%d")
    curhour=int(datetime.datetime.now().strftime("%H"))
    curmin=int(datetime.datetime.now().strftime("%M"))
    
    if curhour >= 8 and curhour+curmin/60 < shiftHour[0]:
        curshift='白'
    else:
        curshift='中'
    
    sqlfun="UPDATE assembly.errorproofing SET visible = 1 "\
            "  WHERE errorproofing_date = '%s' and "\
                "errorproofing_shift='%s' and errorproofing_errorid=%d"\
                    %(curdate,curshift,errorID)
    try:
        cur.execute(sqlfun)
    except Exception as e:
        print ("Error: unable to update errorVisible. Code:",e,errorID,sqlfun)

    cnx.commit()
    cur.close()
    cnx.close()

def R2HUN(hunR):
    try:
        HUN=''
        a=''
        for i in range(9):
            try:
                if hunR[i] not in [0,'0']:
                    a = str(unhexlify(hex(hunR[i])[4:6]))[2]+str(unhexlify(hex(hunR[i])[2:4]))[2]
            except:
                a = ''
            HUN+=a
    except:
        pass
    try:
        b = HUN.index('HD')
        HUN = HUN[b:(b+14)]
    except:
        try:
            c = HUN.index('BH')
            HUN = HUN[c:(c+16)]
        except:
            pass
    return HUN

def wordToReal(word1,word2):
    def wordToBin(word):
        bintemp = bin(word)[2:]
        bintemp = '0' * (16 - len(bintemp)) + bintemp
        return bintemp
    try:
        word1bin = wordToBin(word1)
        word2bin = wordToBin(word2)

        wordCombine = word2bin +word1bin

        ex = wordCombine[1:9]
        ex1 = int(ex,2) - 127
        ex2 = wordCombine[9:]

        b=0
        c=0
        for i in range(len(ex2)):
            b=2**(-1-i) * int(ex2[i])
            c=c+b

        result=(c+1)*(2**ex1)

        if wordCombine[0] == '1':
            result=(-1)*result
    except Exception as e:
        print(word1,word2,e)
        result = 0.1

    return round(result,4)


def rToValue(r):
    a = ''
    result = []
    resultStr = ''
    rr = []
    
    try:
    
        for i in range(16):
            tmp = ''
            rrtmp=''
            for j in range(4):
                a = str(unhexlify(hex(r[i*4+j])[4:6]))[2] + str(unhexlify(hex(r[i*4+j])[2:4]))[2]
                tmp += a
            rrtmp = tmp.split('*')[1]
            tmp = tmp.split('*')[0]
            
            result.append(tmp)
            rr.append(rrtmp)
            
        resultStr = '_'.join(result)
    except:
        pass
        # print('xxx111')

    return resultStr,result,rr

def updateK2(engineType,camshaftCode,bypass,k2):
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()
    sqlfun = "update assembly.marposs_k2 set k2='%s',time=now() where "\
             "enginetype='%s' and camshaftcode=%d and bypass=%d"\
             %(k2,engineType,camshaftCode,bypass)
    cur.execute(sqlfun)
    cnx.commit()
    cur.close()
    cnx.close()
    

def updateMarpossData(EUN,engineType,tappetClassStr,tappetValueStr,cylValueStr,camValueStr,kStr,supplierCode,errorQueue,k2,bypass = 0):
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()
    curdatetime=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    sqlfun="insert into assembly.marposs(eun,enginetype,"\
            "tappetclass,tappetvalue,cylvalue,camvalue,k,time,camshaft_supplier,bypass,k2)"\
            "values( '%s','%s','%s','%s','%s','%s','%s','%s',%d,%d,'%s')"\
            %(EUN,engineType,tappetClassStr,tappetValueStr,cylValueStr,camValueStr,kStr,curdatetime,supplierCode,bypass,k2)
    try:
        cur.execute(sqlfun)
    except Exception as e:
        print ("Error: unable to insert Marposs data. Code:",e,sqlfun)
        text = 'Error: unable to update data. Code: ' + str(e)
        errorQueue.put(['err',text])

    cnx.commit()
    cur.close()
    cnx.close()


def updateMarpossCheckData(station,EUN,engineType,clearance,supplierCode,errorQueue):
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()
    curdatetime=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    sqlfun="insert into assembly.marposs_check(station,camshaft_supplier,eun,enginetype,"\
            "clearance,time)values( '%s',%d,'%s','%s','%s','%s')"\
            %(station,supplierCode,EUN,engineType,clearance,curdatetime)
    try:
        cur.execute(sqlfun)
    except Exception as e:
        text = 'Error: unable to insert Marposs check data. Code: ' + str(e) + EUN + '  ' + sqlfun
        errorQueue.put(['err',text])

    cnx.commit()
    cur.close()
    cnx.close()

def updateMarpossCamshaftTmp(camCountid,EUN,engineType,supplierCode,errorQueue):
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()
        
    sqlfun="UPDATE assembly.marposs_camshaft_tmp set eun='%s',"\
        "enginetype='%s',camshaft_supplier=%d,time=now() where id=%d"%(EUN,engineType,supplierCode,camCountid)
    try:
        cur.execute(sqlfun)
    except Exception as e:
        text = 'Error: unable to update camshaftTmp data. Code: ' + str(e) +EUN
        errorQueue.put(['err',text])

    cnx.commit()
    cur.close()
    cnx.close()

def getCamshaftSupplierCode(errorEUN,errorQueue):
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()

    sqlfun="select camshaft_supplier from assembly.marposs_camshaft_tmp "\
        "where eun = '%s' limit 1"%(errorEUN)
    try:
        cur.execute(sqlfun)
        camshaftSupplierCode = cur.fetchall()[0][0]
    except Exception as e:
        print ("Error: cannot fetch camshaft supplier code. Code:",e,sqlfun)
        text = 'Error: cannot fetch camshaft supplier code. EUN:' + errorEUN + '  errorCode: ' + str(e)
        errorQueue.put(['err',text])
        camshaftSupplierCode = 9

    cnx.commit()
    cur.close()
    cnx.close()

    return camshaftSupplierCode



def getEngineTypes():
    try:
        cnx=pymysql.connect('10.64.34.11','root','Sgmw5050',"assembly" )
    except:
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()
    sqlfun="SELECT code,type FROM assembly.repair_lb_engine_types;"
    cur.execute(sqlfun)
    data=cur.fetchall()
    cnx.commit()
    cur.close()
    cnx.close()

    N12 = []
    N12A = []
    N15 = []
    N15A = []

    for d in data:
        if d[1] == "N12":
            N12.append(d[0])
        elif d[1] == "N12A":
            N12A.append(d[0])
        elif d[1] == "N15":
            N15.append(d[0])
        elif d[1] == "N15A":
            N15A.append(d[0])

    return set(N12),set(N12A),set(N15),set(N15A)



def getErrorData(staStatus,ip,errorID,errorStation,errorQueue,shiftHour,errorProofingQueue,keyParaQueue):

    lastError=[]
    lenError=len(errorID)
    lastError=[0]*lenError
##    print(lastError)
    masterError=modbus_tcp.TcpMaster(ip, 502)
    masterError.set_timeout(3.0)
    n=0
    errorBUN = ''
    errorCUN = ''
    errorHUN = ''
    OP3090AMaster = [
        'BH1C111111118111',
        'HD1CL2K1111111',
        'BH1C222222228222',
        'HD1CL2K2222222',
        ]
        
    #  这里要写一个函数汇总机型
    
    # N12 = {'RZ','AZ','BW','SM'}
    # N12A = {'HA','CV','NG','NH','CE','CK'}
    # N15 = {'RA','CS'}
    # N15A = {'DF','RE','RC','RF','SA','SB','TB','UV','UW','UX','UY','UZ'}


    N12, N12A, N15, N15A = getEngineTypes()
    engineType = ''
    

    cp = ConfigParser()
    cp.read('camshaftCountConfig.ini')
    camCount = cp.getint('camshaftCount','count')
    bypass = 0
        
    while True:
        n+=1

        try:
            errorTemp = masterError.execute(1,cst.READ_COILS,30000,lenError)
        except BaseException as e:
            errorTemp = lastError
            print('eeexxxxxxxxxxxxxxxx',ip,e)
            text = ip + str(e)
            errorQueue.put(['err',text])
            masterError=modbus_tcp.TcpMaster(ip, 502)
            masterError.set_timeout(3.0)

        try:
            if ip == '10.69.7.63':
                if errorTemp[11] == 1:
                    bypass = 1
                else:
                    bypass = 0
            if ip == '10.69.7.227':
                if errorTemp[10] == 1:
                    bypass = 1
                else:
                    bypass = 0
                    
            for i in range(lenError):
                if errorTemp[i]==1:

                    if errorTemp[i]!=lastError[i]:
                        errorEUN=staStatus[errorStation[i]]['EUN']
                        try:
                            ecode = errorEUN[3:5]
                            if ecode in N12:
                                engineType = 'N12'
                            elif ecode in N12A:
                                engineType = 'N12A'
                            elif ecode in N15:
                                engineType = 'N15'
                            elif ecode in N15A:
                                engineType = 'N15A'
                        except:
                            engineType = 'xxx'

                        if errorEUN=='':
                            errorEUN='XXXXEUN'

                        if errorID[i] == 1001:
                            if errorEUN in OP3090AMaster:
                                errorProofingQueue.put([errorID[i],errorEUN,errorQueue,shiftHour])
                        elif errorID[i] == 1002:
                            if errorEUN in OP3090AMaster:
                                errorProofingQueue.put([errorID[i],errorEUN,errorQueue,shiftHour])
                        elif errorID[i] == 1003:
                            if errorEUN in OP3090AMaster:
                                errorProofingQueue.put([errorID[i],errorEUN,errorQueue,shiftHour])

                        elif errorID[i] in [228,239]:

                            tappetClass = []
                            tappetClassStr = ''
                            tappetValueTemp = ()
                            tappetValue = []
                            tappetValueStr = ''
                            cylValueTemp = ()
                            cylValue = ''
                            camValueTemp = ()
                            camValue = ''
                            k2 = ''
                            k2tmp = ''
                            
                            try:
                                camValueTemp = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30099,64)
                                camValueStr,camValue,_ = rToValue(camValueTemp)
                                time.sleep(0.3)
                                cylValueTemp = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30163,64)
                                cylValueStr,cylValue,_ = rToValue(cylValueTemp)
                                time.sleep(0.3)
                                tappetValueTemp = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30227,64)
                                tappetValueStr,tappetValue,tappetClass = rToValue(tappetValueTemp)
                                tappetClassStr = '_'.join(tappetClass)
                            
                            
                                k = []
                                for j in range(8):
                                    k.append(1000 - (int(cylValue[j]) - int(camValue[j]) - int(tappetValue[j])))
                                for j in range(8,16):
                                    k.append(2700 - (int(cylValue[j]) - int(camValue[j]) - int(tappetValue[j])))
                                kStr = '_'.join([str(round(x/10)) for x in k])
                                ks = [round(x/10) for x in k]

                                try:
                                    if errorID[i] == 228:
                                        if errorTemp[9] == 1:
                                            supplierCode = 0
                                        else:
                                            supplierCode = 1
                                    elif errorID[i] == 239:
                                        if errorTemp[7] == 1:
                                            supplierCode = 0
                                        else:
                                            supplierCode = 1
                                except:
                                    print('xxxxxxxxxxxxxxxxxxxxxxxxxxx')
                                    supplierCode = 9
                                                
                                k2tmp = masterError.execute(1,cst.READ_HOLDING_REGISTERS,31016,16)
                                k2 = [str((a-2**16)) if a>1000 else str(a) for a in k2tmp]
                                k2 = '_'.join(k2)

                                cams = [0,0]
                                bypass = 0
                                
                                if ip == '10.69.7.63':
                                    cams[0],cams[1],bypass = masterError.execute(1,cst.READ_COILS,30009,3)
                                    masterError.execute(1,cst.WRITE_MULTIPLE_REGISTERS,starting_address=31032,output_value=ks)
                                elif ip == '10.69.7.227':
                                    cams[0],cams[1],_,bypass = masterError.execute(1,cst.READ_COILS,30007,4)
                                    masterError.execute(1,cst.WRITE_MULTIPLE_REGISTERS,starting_address=31032,output_value=ks)
                                for iCAM in range(2):
                                    if cams[iCAM] == 1:
                                        supplierCode = iCAM

                                
                                if set(k2tmp) != {0}:
                                    updateK2(engineType,supplierCode,bypass,k2)

                                updateMarpossData(
                                    errorEUN,
                                    engineType,
                                    tappetClassStr,
                                    tappetValueStr,
                                    cylValueStr,
                                    camValueStr,
                                    kStr,
                                    supplierCode,
                                    errorQueue,
                                    k2,
                                    bypass
                                    )

                                updateMarpossCamshaftTmp((camCount % 100) + 1,errorEUN,engineType,supplierCode,errorQueue)
                                camCount += 1
                                cp.set('camshaftCount','count',str(camCount))
                                with open("camshaftCountConfig.ini","w+") as f:
                                    cp.write(f)

                            except BaseException as e:
                                print('get marposs data error',ip,e)
                                text = 'get marposs data error' + ip + str(e)
                                errorQueue.put(['err',text])
                                masterError=modbus_tcp.TcpMaster(ip, 502)
                                masterError.set_timeout(3.0)

                        elif errorID[i] == 208:
                            bearCheckRawData = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30100,8)
                            torqueRawData = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30300,8)

                            bearCheckData = {}
                            bearCheckData['dis1'] = bearCheckRawData[0] - bearCheckRawData[1]
                            bearCheckData['dis2'] = bearCheckRawData[2] - bearCheckRawData[3]
                            bearCheckData['dis3'] = bearCheckRawData[4] - bearCheckRawData[5]
                            bearCheckData['dis4'] = bearCheckRawData[6] - bearCheckRawData[7]
                            

                            bearCheckData['max1'] = bearCheckRawData[0]
                            bearCheckData['min1'] = bearCheckRawData[1]
                            bearCheckData['max2'] = bearCheckRawData[2]
                            bearCheckData['min2'] = bearCheckRawData[3]
                            bearCheckData['max3'] = bearCheckRawData[4]
                            bearCheckData['min3'] = bearCheckRawData[5]
                            bearCheckData['max4'] = bearCheckRawData[6]
                            bearCheckData['min4'] = bearCheckRawData[7]

                            bearCheckDataJson = json.dumps(bearCheckData)
                            # insertKeyParaData(bearCheckDataJson,errorEUN,errorStation[i],'bear_check')
                            keyParaQueue.put([bearCheckDataJson,errorEUN,errorStation[i],'bear_check'])


                            torqueData = {}
                            torqueData['peak'] = wordToReal(torqueRawData[0],torqueRawData[1])
                            torqueData['low'] = wordToReal(torqueRawData[2],torqueRawData[3])
                            torqueData['high'] = wordToReal(torqueRawData[4],torqueRawData[5])
                            torqueData['mean'] = wordToReal(torqueRawData[6],torqueRawData[7])

                            torqueDataJson = json.dumps(torqueData)
                            # insertKeyParaData(torqueDataJson,errorEUN,errorStation[i],'TTT')
                            keyParaQueue.put([torqueDataJson,errorEUN,errorStation[i],'TTT'])


                        elif errorID[i] == 209:
                            OP1100ARawData = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30308,16)
                            OP1100ATorqueData = {}
                            OP1100ATorqueData['torque1'] = OP1100ARawData[0]/100
                            OP1100ATorqueData['angle1'] = OP1100ARawData[1]/100
                            OP1100ATorqueData['torque2'] = OP1100ARawData[2]/100
                            OP1100ATorqueData['angle2'] = OP1100ARawData[3]/100
                            OP1100ATorqueData['torque3'] = OP1100ARawData[4]/100
                            OP1100ATorqueData['angle3'] = OP1100ARawData[5]/100
                            OP1100ATorqueData['torque4'] = OP1100ARawData[6]/100
                            OP1100ATorqueData['angle4'] = OP1100ARawData[7]/100
                            OP1100ATorqueData['torque5'] = OP1100ARawData[8]/100
                            OP1100ATorqueData['angle5'] = OP1100ARawData[9]/100
                            OP1100ATorqueData['torque6'] = OP1100ARawData[10]/100
                            OP1100ATorqueData['angle6'] = OP1100ARawData[11]/100
                            OP1100ATorqueData['torque7'] = OP1100ARawData[12]/100
                            OP1100ATorqueData['angle7'] = OP1100ARawData[13]/100
                            OP1100ATorqueData['torque8'] = OP1100ARawData[14]/100
                            OP1100ATorqueData['angle8'] = OP1100ARawData[15]/100

                            OP1100ATorqueDataJson = json.dumps(OP1100ATorqueData)
                            # insertKeyParaData(OP1100ATorqueDataJson,errorEUN,errorStation[i],'torque')
                            keyParaQueue.put([OP1100ATorqueDataJson,errorEUN,errorStation[i],'torque'])


                        elif errorID[i] == 502:
                            OP2050ACrankShaftTorqueRawData = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30100,4)
##                            print(OP2050ACrankShaftTorqueRawData)
                            OP2050ACrankShaftTorqueData = {}
                            if errorEUN[3:5] == 'RA':
                                OP2050ACrankShaftTorqueData['torque1'] = (OP2050ACrankShaftTorqueRawData[2]%32768)/100
                                OP2050ACrankShaftTorqueData['angle1'] = (OP2050ACrankShaftTorqueRawData[3]%32768)/100
                                OP2050ACrankShaftTorqueData['torque2'] = (OP2050ACrankShaftTorqueRawData[0]%32768)/100
                                OP2050ACrankShaftTorqueData['angle2'] = (OP2050ACrankShaftTorqueRawData[1]%32768)/100
                            else:
                                OP2050ACrankShaftTorqueData['torque1'] = (OP2050ACrankShaftTorqueRawData[0]%32768)/100
                                OP2050ACrankShaftTorqueData['angle1'] = (OP2050ACrankShaftTorqueRawData[1]%32768)/100
                                OP2050ACrankShaftTorqueData['torque2'] = (OP2050ACrankShaftTorqueRawData[2]%32768)/100
                                OP2050ACrankShaftTorqueData['angle2'] = (OP2050ACrankShaftTorqueRawData[3]%32768)/100
##                            print(OP2050ACrankShaftTorqueData)

                            OP2050ACrankShaftTorqueDataJson = json.dumps(OP2050ACrankShaftTorqueData)
                            # insertKeyParaData(OP2050ACrankShaftTorqueDataJson,errorEUN,errorStation[i],'torque')
                            keyParaQueue.put([OP2050ACrankShaftTorqueDataJson,errorEUN,errorStation[i],'torque'])

                        elif errorID[i] == 701:
                            OP2320ATorqueRawData = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30114,12)

                            OP2320ATorqueData = {}
                            OP2320ATorqueData['torque1'] = OP2320ATorqueRawData[0]/100
                            OP2320ATorqueData['angle1'] = OP2320ATorqueRawData[1]/100
                            OP2320ATorqueData['torque2'] = OP2320ATorqueRawData[2]/100
                            OP2320ATorqueData['angle2'] = OP2320ATorqueRawData[3]/100
                            OP2320ATorqueData['torque3'] = OP2320ATorqueRawData[4]/100
                            OP2320ATorqueData['angle3'] = OP2320ATorqueRawData[5]/100
                            OP2320ATorqueData['torque4'] = OP2320ATorqueRawData[6]/100
                            OP2320ATorqueData['angle4'] = OP2320ATorqueRawData[7]/100
                            OP2320ATorqueData['torque5'] = OP2320ATorqueRawData[8]/100
                            OP2320ATorqueData['angle5'] = OP2320ATorqueRawData[9]/100
                            OP2320ATorqueData['torque6'] = OP2320ATorqueRawData[10]/100
                            OP2320ATorqueData['angle6'] = OP2320ATorqueRawData[11]/100

                            OP2320ATorqueDataJson = json.dumps(OP2320ATorqueData)
                            # insertKeyParaData(OP2320ATorqueDataJson,errorEUN,errorStation[i],'torque')
                            keyParaQueue.put([OP2320ATorqueDataJson,errorEUN,errorStation[i],'torque'])

                        elif errorID[i] == 702:
                            OP2350ARawData = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30100,14)
                            distanceTmp = OP2350ARawData[:2]
                            torqueTmp = OP2350ARawData[2:]

                            OP2350AData = {}

                            OP2350AData['distance'] = wordToReal(distanceTmp[0],distanceTmp[1])

                            OP2350AData['torque1'] = torqueTmp[0]/100
                            OP2350AData['angle1'] = torqueTmp[1]/100
                            OP2350AData['torque2'] = torqueTmp[2]/100
                            OP2350AData['angle2'] = torqueTmp[3]/100
                            OP2350AData['torque3'] = torqueTmp[4]/100
                            OP2350AData['angle3'] = torqueTmp[5]/100
                            OP2350AData['torque4'] = torqueTmp[6]/100
                            OP2350AData['angle4'] = torqueTmp[7]/100
                            OP2350AData['torque5'] = torqueTmp[8]/100
                            OP2350AData['angle5'] = torqueTmp[9]/100
                            OP2350AData['torque6'] = torqueTmp[10]/100
                            OP2350AData['angle6'] = torqueTmp[11]/100

                            OP2350ADataJson = json.dumps(OP2350AData)
                            # insertKeyParaData(OP2350ADataJson,errorEUN,errorStation[i],'dis_torque')
                            keyParaQueue.put([OP2350ADataJson,errorEUN,errorStation[i],'dis_torque'])

                        elif errorID[i] == 912:
                            OP3060A1ARawData = masterError.execute(1,cst.READ_HOLDING_REGISTERS,30100,1)
                            OP3060A1Data = {}
                            OP3060A1Data['distance'] = OP3060A1ARawData[0]
                            OP3060A1DataJson = json.dumps(OP3060A1Data)
                            # insertKeyParaData(OP3060A1DataJson,errorEUN,errorStation[i],'distance')
                            keyParaQueue.put([OP3060A1DataJson,errorEUN,errorStation[i],'distance'])



                        elif errorID[i] in [313,314]:
                            if errorID[i] == 313:
                                Msta = 'OP1250M'
                                readStart = 30099
                            else:
                                Msta = 'OP1260M'
                                readStart = 30163

                            clearanceValueTemp = masterError.execute(1,cst.READ_HOLDING_REGISTERS,readStart,64)
                            _,clearanceValue,_ = rToValue(clearanceValueTemp)
                            clearanceValueStr = '_'.join(clearanceValue[:8])
                            supplierCode = getCamshaftSupplierCode(errorEUN,errorQueue)
                            updateMarpossCheckData(Msta,errorEUN,engineType,clearanceValueStr,supplierCode,errorQueue)
                        
                        elif errorID[i] in [229,230,238,239,240,241]:
                            pass
                            

                                
                        else:
                            if errorID[i] == 102:
                                errorBUN = R2EUN(masterError.execute(1,cst.READ_HOLDING_REGISTERS,30700,8))
##                                if errorBUN == '':
##                                    time.sleep(0.3)
##                                    errorBUN = R2HUN(masterError.execute(1,cst.READ_HOLDING_REGISTERS,3165,9))
                                errorEUN = errorEUN + '_' + errorBUN
                            elif errorID[i] == 109:
                                errorCUN = R2EUN(masterError.execute(1,cst.READ_HOLDING_REGISTERS,30709,8))
##                                if errorCUN == '':
##                                    time.sleep(0.3)
##                                    errorCUN = R2HUN(masterError.execute(1,cst.READ_HOLDING_REGISTERS,3315,9))
                                errorEUN = errorEUN + '_' + errorCUN
                            elif errorID[i] == 205:
                                errorHUN = R2EUN(masterError.execute(1,cst.READ_HOLDING_REGISTERS,30060,8))
##                                if errorHUN == '':
##                                    time.sleep(0.3)
##                                    errorHUN = R2HUN(masterError.execute(1,cst.READ_HOLDING_REGISTERS,3415,9))
                                errorEUN = errorEUN + '_' + errorHUN
                            # updateDatabase(errorID[i],errorEUN,errorQueue,shiftHour)
                            errorProofingQueue.put([errorID[i],errorEUN,errorQueue,shiftHour])
                        
                        
                        text = 'ErrorProofing: ' + errorStation[i] + '  errorID:' + str(errorID[i]) + '  ' + ' EUN:' + errorEUN
                        errorQueue.put(['info',text])
                        time.sleep(0.05)
                        lastError[i]=errorTemp[i]
##                        print('lastError:',lastError)

                elif errorTemp[i]==0:
                    lastError[i]=errorTemp[i]

        except BaseException as e:
            print('errorP record ERROR:',e)
            print(ip)
            text = str(e) + '  ' + str(errorID[i]) + ' ' + staStatus[errorStation[i]]['EUN'] +ip
            errorQueue.put(['err',text])

        time.sleep(1.1)


def int2bin(a):
    a=bin(int(str(a),10))
    a='0'*(16-len(a)+2)+a[2:]
    return a

def R2EUN(eunR):
    lenR = len(eunR)
    EUN=''
    a = ''
    b = ''
    for i in range(lenR):
        try:
            a = str(unhexlify(hex(eunR[i])[-4:-2]))[2]
            if a.lower() not in 'abcdefghijklmnopqrstuvwxyz0123456789-':
                a = ''
        except:
            a = ''
        try:
            b = str(unhexlify(hex(eunR[i])[-2:]))[2]
            if b.lower() not in 'abcdefghijklmnopqrstuvwxyz0123456789-':
                b = ''
        except:
            b = ''
        EUN = EUN+b+a
                
    return EUN

# def R2EUN(eunR):
#     EUN=''
#     a=''
#     for i in range(7):
#         try:
#             a+=str(unhexlify(hex(eunR[i])[4:6]))[2]+str(unhexlify(hex(eunR[i])[2:4]))[2]
#         except:
#             pass
#     if len(eunR) > 7:
#         i = 7
#         try:
#             a+=str(unhexlify(hex(eunR[i])[4:6]))[2]+str(unhexlify(hex(eunR[i])[2:4]))[2]
#             if len(eunR) == 9:
#                 a+=str(unhexlify(hex(eunR[8])[2:4]))[2]
#         except:
#             pass
#     EUN+=a

#     return EUN

def getStaData(staStatus,station,ip,n,stationB,stationP,stationPalletno,errorQueue,keyParaQueue):

    master = modbus_tcp.TcpMaster(ip, 502)
    master.set_timeout(3.0)

    def wordToBin(word):
        bintemp = bin(word)[2:]
        bintemp = '0' * (16 - len(bintemp)) + bintemp
        a = bintemp[:8]
        b = bintemp[8:]
        bintemp = b + a
        
        return bintemp


    stasAuto = ['1010M','2490M','1430M-1','2010M','1250M','1260M','2130A-1','2130A-2','1020A','1030A',
                '1050M','1055M','1060M','1080A','1090M','1100M','1110A','1120A','1140M','1150M',
                '1160A','1170M','1180M','1190A','1220M','1230M','1240A','1270M','1280M','1300M',
                '1261M','1275A','1290A','1310A','1320A','1330M','1340M','1350A-1','1350A-2','1360M','1370A',
                '1380M','1390M','1400A-1','1400A-2','1410M','1420M','2010M','2020M','2030M','2060M','2070M',
                '2080M','2090M','2110M','2140M','2170M','2180A','2190M','2230M','2360M','2390M','2400M',
                '2410M','2460M','2470M','2480M','1210S1','2050A-1','2050A-2','2290M','2310M','2370M',
                '2475A','1210S3','2250M','2320M','2350A','2240M','2280M','2300M','2340M']

    stasBypass = ['1010M','2490M','1430M-1','2010M','1250M','1260M','2130A-1','2130A-2','1020A','1030A',
                '1050M','1055M','1060M','1080A','1090M','1100M','1110A','1120A','1140M','1150M',
                '1160A','1170M','1180M','1190A','1220M','1230M','1240A','1270M','1280M','1300M',
                '1261M','1275A','1290A','1310A','1320A','1330M','1340M','1350A-1','1350A-2','1360M','1370A',
                '1380M','1390M','1400A-1','1400A-2','1410M','1420M','2010M','2020M','2030M','2060M','2070M',
                '2080M','2090M','2110M','2140M','2170M','2180A','2190M','2230M','2360M','2390M','2400M',
                '2410M','2460M','2470M','2480M','1210S1','2050A-1','2050A-2','2290M','2310M','2370M',
                '2475A','1210S3','2250M','2320M','2350A','2240M','2280M','2300M','2340M']

    # N12 = ['RZ','AZ','BW','SM','HA','CV','NG','NH','CE','CK']

    # N15 = ['RA','CS','DF','RE','RC','RF','SA','SB','TB','UV','UW','UX','UY','UZ']

    ET = getEngineTypes()
    N12 = list(ET[0]) + list(ET[1])
    N15 = list(ET[2]) + list(ET[3])

    leak1 = []
    leak2 = []
    st = time.time()
    lastdis2350 = 0
    lastdis3060a1 = 20
    lastop2350 = 0
    while True:
        time.sleep(0.5)
        
        try:
            dataPresent=master.execute(1,cst.READ_COILS,30200,len(stationP))    
            for i in range(len(stationP)):
                tmp=staStatus[stationP[i]]
                tmp['present']=dataPresent[i]
                staStatus[stationP[i]]=tmp
##            time.sleep(0.2)

            
            dataBuildable=master.execute(1,cst.READ_COILS,30400,len(stationB))
            for i in range(len(stationB)):
                tmp=staStatus[stationB[i]]
                tmp['buildable']=dataBuildable[i]
                staStatus[stationB[i]]=tmp
##            time.sleep(0.2)

            
            if ip == '10.69.7.21':
                dataPalletno=master.execute(1,cst.READ_HOLDING_REGISTERS,30600,len(stationPalletno))
            else:
                dataPalletno=master.execute(1,cst.READ_HOLDING_REGISTERS,30000,len(stationPalletno))
            for i in range(len(stationPalletno)):
                tmp=staStatus[stationPalletno[i]]
                tmp['palletno']=dataPalletno[i]
                staStatus[stationPalletno[i]]=tmp
##            time.sleep(0.2)

            for i in range(n):
                if ip in ['10.69.7.227','10.69.7.63','10.69.8.36','10.69.8.38']:
                    dataRTemp=master.execute(1,cst.READ_HOLDING_REGISTERS,4599+120*i,120)
                elif ip in ['10.69.7.239','10.69.7.237','10.69.7.212','10.69.7.215','10.69.7.219','10.69.7.212']:
                    dataRTemp=master.execute(1,cst.READ_HOLDING_REGISTERS,2000+120*i,120)
                else:
                    dataRTemp=master.execute(1,cst.READ_HOLDING_REGISTERS,2030+120*i,120)
                
            
                for j in range(4):
                    other = 'XXX'
                    try:
                        sta=station[j+i*4]
                        goodpiece=dataRTemp[16+j*30]
                        rejectpiece=dataRTemp[17+j*30]
                        lastcycle=dataRTemp[19+j*30]
                        currentcycle=dataRTemp[22+j*30]

                        if ip in ['10.69.8.13','10.69.8.20','10.69.8.36','10.69.8.38']:
                            EUN=R2HUN(dataRTemp[(6+30*j):(15+30*j)])
                        else:
##                            if sta not in ['1010M']:
                            EUN=R2EUN(dataRTemp[(6+30*j):(15+30*j)])

                        if sta in ['1445R','2515R']:
                            otherTmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30050,2)
                            otherTmp = {'reject':[otherTmp[0]],'reload':[otherTmp[1]]}
                            other = json.dumps(otherTmp)
                            
                        elif sta == '1010M':
                            # if EUN[3:5] in N15:
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30700,8)
                            # else:
                            #     tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30700,7)
##                            print(sta,tmp)
##                            ttmp = R2EUN(tmp[:9])
##                            if ttmp != '':
##                                EUN = ttmp
                            ttmp = R2EUN(tmp)
                            if ttmp != '':
                                otherTmp = {'block':[ttmp]}
                            else:
                                otherTmp = {'block':[ttmp]}
##                            print(sta,'otherTmp',otherTmp)
                            other = json.dumps(otherTmp)
##                            print(other)
                            
                        elif sta == '1060M':
                            # if EUN[3:5] in N15:
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30709,8)
                            # else:
                            #     tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30709,7)
                            ttmp = R2EUN(tmp)
                            if ttmp != '':
                                otherTmp = {'crank':[ttmp]}
                                other = json.dumps(otherTmp)
                            
                        elif sta == '1170M':
                            # if EUN[3:5] in N15:
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30060,8)
                            # else:
                            #     tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30060,7)
                            ttmp = R2EUN(tmp)
                            if ttmp != '':
                                otherTmp = {'cylinder':[ttmp]}
                                other = json.dumps(otherTmp)

                        elif sta == '2130A-1':
                            # print('#################',time.time()-st)
                            # st = time.time()
                            if EUN[3:5] in N12:
                                tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30050,4)
                                waterTmp = wordToReal(tmp[0],tmp[1])
                                oilTmp = wordToReal(tmp[2],tmp[3])
                                if oilTmp != 0 and waterTmp != 0:
                                    otherTmp = {'oilleak':[oilTmp],'waterleak':[waterTmp]}
                                    other = json.dumps(otherTmp)
                                else:
                                    other = json.dumps('XXX')
                            else:
                                other = json.dumps('XXX')

                        elif sta == '2130A-2':
                            if EUN[3:5] in N15:
                                tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30054,4)
                                waterTmp = wordToReal(tmp[0],tmp[1])
                                oilTmp = wordToReal(tmp[2],tmp[3])
                                # print('#############',oilTmp,waterTmp)
                                if oilTmp != 0 and waterTmp != 0:
                                    otherTmp = {'oilleak':[oilTmp],'waterleak':[waterTmp]}
                                    other = json.dumps(otherTmp)
                                else:
                                    other = json.dumps('XXX')
                            else:
                                other = json.dumps('XXX')
                            # print('@@@@@@@@@@@@@@@',len(other),other)

                        elif sta == '2350A':
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30100,4)
                            dis1 = wordToReal(tmp[0],tmp[1])
                            dis2 = wordToReal(tmp[2],tmp[3])
                            if dis1 != 0 and dis2 != 0 :
                                otherTmp = {'dis1':[dis1],'dis2':[dis2]}
                                other = json.dumps(otherTmp)
                            else:
                                other = json.dumps('XXX')
                        
                        elif sta == '2050A-2':
                            # if EUN[3:5] in N15:
                            OP2050ACrankShaftTorqueRawData = master.execute(1,cst.READ_HOLDING_REGISTERS,30100,4)
                            OP2050ACrankShaftTorqueData = {}
                            OP2050ACrankShaftTorqueData['torque1'] = (OP2050ACrankShaftTorqueRawData[0]%32768)/100
                            OP2050ACrankShaftTorqueData['angle1'] = (OP2050ACrankShaftTorqueRawData[1]%32768)/100
                            OP2050ACrankShaftTorqueData['torque2'] = (OP2050ACrankShaftTorqueRawData[2]%32768)/100
                            OP2050ACrankShaftTorqueData['angle2'] = (OP2050ACrankShaftTorqueRawData[3]%32768)/100
                            OP2050ACrankShaftTorqueDataJson = json.dumps(OP2050ACrankShaftTorqueData)

                            if OP2050ACrankShaftTorqueData['torque1']+OP2050ACrankShaftTorqueData['angle1'] not in [lastop2350,0]:
                                keyParaQueue.put([OP2050ACrankShaftTorqueDataJson,EUN,'2050A-2','torque'])
                                otherTmp = {'torque':[OP2050ACrankShaftTorqueData['torque1']],'angle':[OP2050ACrankShaftTorqueData['angle1']]}
                                other = json.dumps(otherTmp)
                                lastop2350 = OP2050ACrankShaftTorqueData['torque1']+OP2050ACrankShaftTorqueData['angle1']
                            else:
                                other = json.dumps('XXX')




                        elif sta == '3060A1':
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30100,4)
                            dis1 = wordToReal(tmp[0],tmp[1])
                            dis2 = wordToReal(tmp[2],tmp[3])
                            if dis1 != 0 and dis2 != 0 :
                                otherTmp = {'dis1':[dis1],'dis2':[dis2]}
                                # print('@@@@@@@@@@@@@@@@@ OP3060A1:',dis1,dis2,otherTmp)
                                other = json.dumps(otherTmp)
                            else:
                                other = json.dumps('XXX')
                            # print('################## OP3060A1:',dis1,dis2,other)

                        elif sta == '2170M':
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30099,8)
                            flywheel = R2EUN(tmp)
                            if len(flywheel) != 0:
                                otherTmp = {'flywheel':[flywheel]}
                                other = json.dumps(otherTmp)
                            else:
                                other = json.dumps('XXX')

                        elif sta == '2340M':
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30201,7)
                            clutch = R2EUN(tmp)
                            if len(clutch) != 0:
                                otherTmp = {'clutch':[clutch]}
                                other = json.dumps(otherTmp)
                            else:
                                other = json.dumps('XXX')

                        elif sta == '1261M':
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30299,16)
                            intake = R2EUN(tmp[:7])
                            exh = R2EUN(tmp[9:15])
                            if len(intake) !=0 and len(exh) != 0:
                                otherTmp = {'chainwheelint':[intake],'chainwheelexh':[exh]}
                                other = json.dumps(otherTmp)
                            else:
                                other = json.dumps('XXX')

                        elif sta == '2470M':
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30050,2)
                            waterTmp = wordToReal(tmp[0],tmp[1])
                            if waterTmp != 0:
                                otherTmp = {'waterleak':[waterTmp]}
                                other = json.dumps(otherTmp)

                        elif sta == '3090A':
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30100,16)
                            leakTmp = [0]*8
                            for lrt in range(8):
                                leakTmp[lrt] =  wordToReal(tmp[2*lrt],tmp[2*lrt+1])
                            if 0 not in leakTmp:
                                otherTmp = {
                                    'intleak1':[leakTmp[0]],'intleak2':[leakTmp[1]],
                                    'intleak3':[leakTmp[2]],'intleak4':[leakTmp[3]],
                                    'exhleak1':[leakTmp[4]],'exhleak2':[leakTmp[5]],
                                    'exhleak3':[leakTmp[6]],'exhleak4':[leakTmp[7]],
                                    }
                                other = json.dumps(otherTmp)
                                
                        elif sta == '3100A':
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,30119,4)
                            torques = [0,0,0,0]
                            for tt in range(4):
                                torques[tt] = tmp[tt]/1000
                            if 0 not in torques:
                                otherTmp = {
                                    'cyl1':[torques[0]],
                                    'cyl2':[torques[1]],
                                    'cyl3':[torques[2]],
                                    'cyl4':[torques[3]],
                                    }
                                other = json.dumps(otherTmp)

                        elif sta in ['1210S3','1210S1']:
                            tmp = master.execute(1,cst.READ_HOLDING_REGISTERS,2215,17)
                            camIntR = tmp[:7]
                            camExhR = tmp[10:]

                            camInt = R2EUN(camIntR)
                            camExh = R2EUN(camExhR)

                            if len(camInt)>10 and len(camExh)>10:
                                otherTmp = {
                                    'camInt':[camInt],'camExh':[camExh]
                                }
                                other = json.dumps(otherTmp)
                        
                                        
                        assistance=int2bin(dataRTemp[5+j*30])
                        teamleader=int(assistance[-1])
                        maintenance=int(assistance[-2])

                        andon=int2bin(dataRTemp[2+j*30])

                        blocked=int(andon[-3])
                        starved=int(andon[-4])
                        fault=int(andon[-5])
                        auto=int(andon[-1])
                        
                        if sta in stasBypass:
                            bypass=int(andon[-12])
                        else:
                            bypass = 0

                        temp=staStatus[sta]
                        if EUN != '':
                            temp['EUN']=EUN
                        temp['goodpiece']=goodpiece
                        temp['rejectpiece']=rejectpiece
                        temp['lastcycle']=lastcycle
                        temp['currentcycle']=currentcycle
                        temp['teamleader']=teamleader
                        temp['maintenance']=maintenance
                        temp['blocked']=blocked
                        temp['starved']=starved
                        temp['fault']=fault
                        temp['bypass']=bypass
                        if sta in stasAuto:
                            temp['auto']=auto
                        else:
                            temp['auto']=1
                        temp['other'] = other
                        staStatus[sta]=temp
                    except Exception as e:
                        if sta in ['1445R','2515R']:
                            print('!!!!!!!!!!!!!!@@@@@@@@@@@#############\n',ip,sta,e)
##                time.sleep(0.5)
      
                
                
        except BaseException as e:
            if ip == "10.69.8.38":
                pass
            else:
                print('error:',e, ip)
                text = ip + ' ' + str(e)
                errorQueue.put(['err',text])
                time.sleep(1)
                master = modbus_tcp.TcpMaster(ip, 502)
                master.set_timeout(3.0)
          

def staRecord(eun,station,pano,lastcycle,currentcycle,goodpiece,rejectpiece,other = ''):
    if other == 'XXX':
        other = json.dumps(other)
    try:
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
        cur=cnx.cursor()
        # if station in ['1445R','2515R','1010M','1060M','1170M','3090A','1210S3','1210S1','2130A-1','2130A-2']:
        if other != '':
            sqlfun=("insert into assembly.output_loopa(EUN,station,PANO,last_cycle_time,current_cycle_time"\
                ",goodpiececount,rejectpiececount,time,other)values('%s','%s','%d','%d','%d','%d','%d',now(),'%s')"\
                    %(eun,station,pano,lastcycle,currentcycle,goodpiece,rejectpiece,other))
        else:
            sqlfun=("insert into assembly.output_loopa(EUN,station,PANO,last_cycle_time,current_cycle_time"\
                ",goodpiececount,rejectpiececount,time)values('%s','%s','%d','%d','%d','%d','%d',now())"\
                    %(eun,station,pano,lastcycle,currentcycle,goodpiece,rejectpiece))
        cur.execute(sqlfun)
        cnx.commit()
        cur.close()
        cnx.close()
    except BaseException as e:
       print ("staRecord Error: unable to insert data",e,sqlfun)

def errorProofingRecord(errorProofingQueue,errorQueue):
    while 1:
        if errorProofingQueue.qsize() > 0:
            for i in range(errorProofingQueue.qsize()):
                tmp = errorProofingQueue.get()
                # print(tmp)
                updateDatabase(
                    tmp[0],
                    tmp[1],
                    tmp[2],
                    tmp[3]
                )
        time.sleep(1)



def keyParaDataRecord(keyParaQueue):
    def insertKeyParaData(keyParaDataJson,eun,station,datatype):
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
        cur=cnx.cursor()
        
        sqlfun="insert into assembly.key_para(station,datatype,eun,key_para)"\
            "values('%s','%s','%s','%s')"%(station,datatype,eun,keyParaDataJson)
        cur.execute(sqlfun)
        cnx.commit()
        cur.close()
        cnx.close()

    while 1:
        if keyParaQueue.qsize() > 0:
            for i in range(keyParaQueue.qsize()):
                tmp = keyParaQueue.get()
                # print(tmp)
                try:
                    insertKeyParaData(
                        tmp[0],
                        tmp[1],
                        tmp[2],
                        tmp[3]
                    )

                except Exception as e:
                    text = 'Error: cannot insert key-para data . EUN:' + tmp[1] + '  ' +tmp[2] +'  errorCode: ' + str(e)
                    errorQueue.put(['err',text])
        time.sleep(1)
                    

def layoutRecord(staSequence,staStatus):
    global LoopAFirst,LoopBFirst,LoopASecond,LoopBSecond,Q_LAYOUT_ANDON
    def record(stasPresent):
        try:
            cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
            cur=cnx.cursor()
            sqlfun=("insert into assembly.layout(layout_time,layout_stacom)values(now(),'%s')"%(stasPresent))
            cur.execute(sqlfun)
            cnx.commit()
            cur.close()
            cnx.close()
        except BaseException as e:
            print ("layoutRecord Error: unable to insert data",e)

    def convertStaPresent(station,staStatus):
        status = ''

        if staStatus[station]['maintenance'] in [1,'1']:
            status = 3
        elif staStatus[station]['teamleader'] in [1,'1']:
            status = 4
        elif staStatus[station]['bypass'] in [1,'1']:
            status = 8
        elif staStatus[station]['fault'] in [1,'1']:
            status = 2
        elif staStatus[station]['blocked'] in [1,'1']:
            status = 6
        elif staStatus[station]['starved'] in [1,'1']:
            status = 5
        elif staStatus[station]['auto'] in [0,'0']:
            status = 7
        else:
            status = staStatus[station]['present']

        return status

    def getShiftHour():
        cnx=pymysql.connect('127.0.0.1','CHUAN','password',"assembly" )
        cur=cnx.cursor()
        sqlfun = "SELECT shift,restday,single_shift_starttime,single_shift_dur FROM assembly.shift_hour order by id desc limit 1"
        cur.execute(sqlfun)
        shiftHour,restDay,single_shift_starttime,single_shift_dur = cur.fetchall()[0]
        if len(restDay) == 0:
            restDays = [9]
        else:
            restDays = [int(x) for x in restDay]
        cnx.commit()
        cur.close()
        cnx.close()
        data = []

        return shiftHour,restDays,single_shift_starttime,single_shift_dur

    def getJPHTarget():
        try:
            cnx=pymysql.connect('127.0.0.1','CHUAN','password',"assembly" )
            cur=cnx.cursor()
            sqlfun = "SELECT JPH FROM assembly.shift_hour order by id desc limit 1"
            cur.execute(sqlfun)
            jph = cur.fetchall()[0][0]
            cnx.commit()
            cur.close()
            cnx.close()
        except Exception as e:
            print(e)
            jph = 67
        return jph

    def getHourTargetRests(jph):
        cnx=pymysql.connect('127.0.0.1','CHUAN','password',"assembly" )
        cur=cnx.cursor()
        sqlfun = 'select target,rest from assembly.shift_target_rest where jph=%d limit 1'%jph
        cur.execute(sqlfun)
        y = cur.fetchall()[0]
        cnx.commit()
        cur.close()
        cnx.close()

        rests= eval(json.loads(y[1]))
        hourTargets= eval(json.loads(y[0]))
        
        return hourTargets,rests
    

    miniRests = [
        [0, 0, 0, [10, 0], [30, 30], 0, 0, [10, 0], 0, 0, 0, [30, 0], 0, [10, 0], 0, [10, 0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, [10, 0], [30, 30], 0, 0, [10, 30], 0, 0, 0, 0, 0, [30, 0], 0, [10, 0], 0, [10, 0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, [10, 0], [30, 30], 0, 0, [10, 0], 0, [10, 0], 0, 0, 0, [10, 0], 0, [30, 0], 0, [10, 0], 0, [10, 0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, [10, 0], [30, 30], 0, 0, [10, 0], 0, [10, 0], [10, 30], 0, 0, 0, [10, 0], 0, [30, 0], 0, [10, 10], [10, 50], 0, [10, 30], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        ]
    
    shiftHour,restDays,single_shift_starttime,single_shift_dur = getShiftHour()

    jph = getJPHTarget()
    hourCountTargets,miniRests = getHourTargetRests(jph)

    miniRest = miniRests[shiftHour-8]
        
    nn = 1
    
    while 1:
        try:
            curtime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            curDate = datetime.datetime.now().strftime("%Y-%m-%d")
            yesterday = (datetime.datetime.now() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d")
            curHour = int(datetime.datetime.now().strftime("%H"))
            curMinute = int(datetime.datetime.now().strftime("%M"))
            curSecond = int(datetime.datetime.now().strftime("%S"))
            curWeekDay = datetime.datetime.now().weekday()
            
            stasPresent = ''
            curhour=int(datetime.datetime.now().strftime("%H"))
            for sta in staSequence:
                stasPresent += str(convertStaPresent(sta,staStatus))
            Q_LAYOUT_ANDON.put(stasPresent)

            # LoopAFirst,LoopASecond,LoopBFirst,LoopBSecond = updateAsPerhourOut()
            # print("single_shift_starttime:",single_shift_starttime)
            # print("single_shift_dur:",single_shift_dur)
            # print("curhour:",curhour)

            if single_shift_starttime is not None and \
                (curhour >= single_shift_starttime and curhour < 24) or \
                (single_shift_starttime+single_shift_dur>24 and curhour < single_shift_starttime+single_shift_dur):
                
                # print('xxx')
                # print("A",LoopAFirst, LoopASecond)
                # print("B",LoopBFirst, LoopBSecond)
                loopACount = ((LoopAFirst + LoopASecond)[int(single_shift_starttime - 8) : int(single_shift_starttime + 12 - 8)]+[0]*12)[:12]
                loopBCount = ((LoopBFirst + LoopBSecond)[int(single_shift_starttime - 8) : int(single_shift_starttime + 12 - 8)]+[0]*12)[:12]
            else:
                # print('yyyy')
                if curhour >= 8 and (curhour+curMinute/60) < shiftHour:
                    loopACount = LoopAFirst
                    loopBCount = LoopBFirst
                    # print('###################################   白班  ###################################')
                else:
                    loopACount = LoopASecond
                    loopBCount = LoopBSecond
                    # print('###################################   中班  ###################################')
            # print(loopACount)
            # print(loopBCount)

            loopACountStr = ''.join([str(x)[-2:] if len(str(x))>1 else '0'+str(x) for x in loopACount])
            loopBCountStr = ''.join([str(x)[-2:] if len(str(x))>1 else '0'+str(x) for x in loopBCount])
            stasPresent = stasPresent + loopACountStr + loopBCountStr


            # print("loopACountStr: ",loopACountStr)


            

            restDaysLen = len(restDays)
            restFlag = False
            miniRestFlag = False
            if restDaysLen == 1:
                if curWeekDay == restDays[0]:
                    if single_shift_starttime is None:
                        if curHour >= ((shiftHour-8)*2+8-24):
                            restFlag = True
                    else:
                        if curHour > single_shift_starttime + single_shift_dur or \
                            curHour < 8 and curHour > (single_shift_starttime + single_shift_dur)%24:
                            restFlag = True
                print("restFlag1:",restFlag)
                
            elif restDaysLen > 1:
                if curWeekDay in restDays[1:]:
                    restFlag = True
                    print("restFlag2:",restFlag)
                elif curWeekDay == restDays[0] and curHour >= ((shiftHour-8)*2+8-24):
                    restFlag = True
                    print("restFlag3:",restFlag)

            if (restDays[-1] + 1)%7 == curWeekDay and (curHour < 8 and curHour > (single_shift_starttime + single_shift_dur)%24):
                restFlag = True
                print("restFlag4:",restFlag)

            if restDaysLen == 1 and restDays[0] == 9:
                restFlag = False

            if curHour >= 2*shiftHour-32 and curHour < 8:
                restFlag = True
                print("restFlag5:",restFlag)

   
            if curHour > 7:
                rt = miniRest[curHour-7]
            else:
                rt = miniRest[curHour+17]

            if rt != 0:
                if curMinute >= rt[1] and curMinute < (rt[1] + rt[0]):
                    miniRestFlag = True
            
            if restFlag == True:
                stasPresent = '!' + stasPresent[1:]
            elif miniRestFlag == True:
                stasPresent = '@' + stasPresent[1:]

            record(stasPresent)
            time.sleep(1.9)
            nn += 1
            if nn%60 == 0:
                shiftHour,restDays,single_shift_starttime,single_shift_dur = getShiftHour()
                miniRest = miniRests[shiftHour-8]
                # miniRest = miniRests[shiftHour-16]
        except Exception as e:
            print('record layout error')
            print(e)
            time.sleep(1.6)

def outut_perhourRecord(loopaCount,loopbCount,shiftHour):
##    print(00000000000000000000000)
    curdate=datetime.datetime.now().strftime("%Y-%m-%d")
    curhour=datetime.datetime.now().strftime("%H")
    curmin=int(datetime.datetime.now().strftime("%M"))

    try:
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
        cur=cnx.cursor()
        sqlfun1 = "select output_perhour_date from assembly.output_perhour "\
            "order by output_perhour_id desc limit 1 "
        cur.execute(sqlfun1)
        lastDate = cur.fetchall()[0][0]
##        print(lastDate,lastDate.strftime("%Y-%m-%d"),curdate)
        if lastDate.strftime("%Y-%m-%d") != curdate:
            sqlfun1=("insert into assembly.output_perhour(output_perhour_date)values('%s')"%(curdate))
            cur.execute(sqlfun1)
            print('Date changed, insert %s to.....'%curdate)

        try:
##            print(111111111111111111111111)
            if int(curhour) == int(shiftHour) and curmin < ceil(60*(shiftHour - int(shiftHour))):
                sqlfun="UPDATE assembly.output_perhour SET output_perhour_1430_%s=%d,"\
                    "output_perhour_1430_total=%d,output_perhour_2490_total=%d,"\
                    "output_perhour_2490_%s=%d,loopa_append=%d,loopb_append=%d"\
                        " WHERE output_perhour_date='%s'"\
                        %(curhour,loopaCount,loopaCount,loopbCount,curhour,loopbCount,loopaCount,loopbCount,curdate)
##                print(22222222222222222222222)

            else:
                sqlfun="UPDATE assembly.output_perhour SET output_perhour_1430_%s=%d,"\
                    "output_perhour_1430_total=%d,output_perhour_2490_total=%d,"\
                    "output_perhour_2490_%s=%d WHERE output_perhour_date='%s'"\
                        %(curhour,loopaCount,loopaCount,loopbCount,curhour,loopbCount,curdate)
##                print(33333333333333333)

            cur.execute(sqlfun)
            cnx.commit()
        except BaseException as e:
            print(curdate,e)            
            cur.execute(sqlfun)
            cnx.commit()
            
        cur.close()
        cnx.close()
    except BaseException as e:
       print ("output_perhourRecord Error: unable to insert data",e)

def insertErrorproofingDefault():
    curdate = datetime.datetime.now().strftime("%Y-%m-%d")
    cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
    cur=cnx.cursor()
    sqlfun = 'select errorproofing_date from assembly.errorproofing order by errorproofing_id desc limit 1'
    cur.execute(sqlfun)
    lastDate = cur.fetchall()[0][0]
    shifts = ['白','中']
    if lastDate.strftime("%Y-%m-%d") != curdate:
        sqlfun = 'select * from assembly.errorproofing_default'
        cur.execute(sqlfun)
        errorproofingDefault = cur.fetchall()
        for shift in shifts:
            for ep in errorproofingDefault:
                errorID = ep[1]
                errorStation = ep[4]
                errorDetail = ep[5]
                errorVisible = ep[8]
                sqlfun = "INSERT INTO `assembly`.`errorproofing` (`errorproofing_errorid`,"\
                         "`errorproofing_date`, `errorproofing_time`, `errorproofing_station`,"\
                         " `errorproofing_detail`, `errorproofing_occured`, `errorproofing_shift`"\
                         ", `visible`)VALUES (%d,'%s',now(),'%s','%s','X','%s',%d);"\
                         %(errorID,curdate,errorStation,errorDetail,shift,errorVisible)
                cur.execute(sqlfun)
    cnx.commit()
    cur.close()
    cnx.close()

def getAsData(station,cycleStandard):
    
    # 获取当前时间
    current_time = datetime.datetime.now()
    current_time_string = current_time.strftime("%Y-%m-%d %H:%M:%S")
    # 计算当前日期8点的时间
    eight_in_the_morning = current_time.replace(hour=8, minute=0, second=0, microsecond=0)

    # 如果当前时间已超过8点，则取当天的8点，否则取昨天的8点
    if current_time.time() < eight_in_the_morning.time():
        eight_in_the_morning -= datetime.timedelta(days=1)
    # 转换为字符串
    eight_in_the_morning_string = eight_in_the_morning.strftime("%Y-%m-%d %H:%M:%S")

    # 输出当前时间
    print(current_time_string)
    print(eight_in_the_morning_string)
    
    if 'R' in station:
        limitNo = 1
    else:
        limitNo = 100
    try:
        cnx=pymysql.connect('127.0.0.1','CHUAN','password',"assembly" )
        cur=cnx.cursor()
        # sqlfun = "select * from assembly.output_loopa where station = '%s' "\
        #          "order by id desc limit %d"%(station,limitNo)
        
        sqlfun = (
            "select * from assembly.output_loopa where station = '%s' and time between '%s' AND '%s' order by id desc"
            % (station, eight_in_the_morning_string, current_time_string)
        )
        cur.execute(sqlfun)
        data=cur.fetchall()
        cnx.commit()
        cur.close()
        cnx.close()
        cycletmp = [x[4] for x in data]
        
##        a = cycletmp.count(0)
##
##        for i in range(a):
##            cycletmp.remove(0)
        cycletmp = cycletmp[::-1]
        for i in range(len(cycletmp)-1,-1,-1):
            if cycletmp[i] <= 200 or cycletmp[i] >= 900:
                del cycletmp[i]

        if station in ['1430M-1']:
            for i in range(len(cycletmp)-1,0,-1):
                if cycletmp[i] - cycletmp[i-1] >= 300:
                    # print(data[i])
                    cycletmp[i] = cycletmp[i] -cycletmp[i-1]
        

        if len(cycletmp) == 0:
            cycle = 0
            maxcycle = 0
            mincycle = 0
            overcycle = 0
            # 新增两个字段 author:davidhu
            overcycle_positive = 0
            overcycle_negative = 0
        else:
            cycle = average(cycletmp)/10
            maxcycle = max(cycletmp)/10
            mincycle = min(cycletmp)/10
            overcycle = 0
            # 新增2个字段
            overcycle_positive = 0
            overcycle_negative = 0
            for xx in cycletmp:
                if xx > cycleStandard:
                    overcycle += 1
                    
            # 新增两个字段的判断 author:davidhu
            for yy in cycletmp:
                if yy > cycleStandard * 1.05:
                    overcycle_positive = overcycle_positive + 1
            for yy2 in cycletmp:
                if yy2 < cycleStandard * 0.95:
                    overcycle_negative =overcycle_negative + 1
            
        good = data[0][6]
        reject = data[0][7]
        try:
            time = data[0][8].strftime("%Y-%m-%d %H:%M:%S")
        except:
            time = 0
        lastCycle = data[0][4]/10
        pano = data[0][3]
        eun = data[0][1][:-4]
        other = data[0][9]
        
    except Exception as e:
        print(e)

    return cycle,good,reject,time,lastCycle,pano,eun,maxcycle,mincycle,overcycle,other,overcycle_positive,overcycle_negative,

def getCycleStandard():
    cnx=pymysql.connect('127.0.0.1','CHUAN','password',"assembly" )
    cur=cnx.cursor()
    sqlfun = 'select cycle from assembly.as_cycle order by id desc limit 1'
    cur.execute(sqlfun)
    y = cur.fetchall()[0][0]
    cnx.commit()
    cur.close()
    cnx.close()
    # cycles = eval(json.loads(y))
    cycles = json.loads(y)

    return cycles


def getStaKeyPara(station,eun,key):
    cnx=pymysql.connect('127.0.0.1','CHUAN','password',"assembly" )
    cur=cnx.cursor()
    sqlfun = "select key_para from (SELECT * FROM assembly.key_para "\
        "where station='%s' and datatype='%s' order by id desc limit 10)"\
            " as a where a.eun='%s'"\
            %(station,key,eun)
    cur.execute(sqlfun)
    y = cur.fetchall()
    cnx.commit()
    cur.close()
    cnx.close()

    if len(y) == 0:
        return ''
    else:
        return json.loads(y[0][0])


def getStaOthers(station,eun):
    pass

def updateFineAs(station):
    keys = {'1120A':'TTT','2050A-2':'torque','1110A':'torque'}
    others = {
        '1010M':'5C','1060M':'5C','1210S3':'5C','1170M':'5C','1210S1':'5C',
        '2350A':'dis','3060A1':'dis','2470M':'leak','2130A-1':'leak',
        '2130A-2':'leak','3090A':'leak','2340M':'clutch','2170M':'flywheel',
        '2050A-2':'torque'
        }
    try:
        cycleStandards = getCycleStandard()
        try:
            if int(station[:4]) in cycleStandards:
                cycleStandard = cycleStandards[int(station[:4])] * 10
            else:
                cycleStandard = 440
        except:
            cycleStandard = 440

        cycle,good,reject,time,lastCycle,pano,eun,maxcycle,mincycle,overcycle,other,overcycle_positive,overcycle_negative = getAsData(station,cycleStandard)

        try:
            ftq = good/(good+reject)
        except:
            ftq = 0
        
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
        cur=cnx.cursor()

        if station in keys:
            a = getStaKeyPara(station,eun,keys[station])
            if a != '':
                if station == '2050A-2' and eun[3:5] == 'TB':
                    pass
                else:
                    a = json.dumps({keys[station]:a})
                    sqlfun="UPDATE assembly.fine_as SET count_good=%d,count_reject=%d,"\
                            "ftq=%f,cycletime=%f,time='%s',eun='%s',lastcycle=%f,pano=%d,"\
                            "maxcycle=%f,mincycle=%f,overcycle=%d,keypara = '%s',overcycle_positive_three=%d,overcycle_negative_three=%d WHERE station = '%s'"\
                            %(good,reject,ftq,cycle,time,eun,lastCycle,pano,maxcycle,mincycle,overcycle,a,overcycle_positive,overcycle_negative,station)
                cur.execute(sqlfun)
            else:
                sqlfun="UPDATE assembly.fine_as SET count_good=%d,count_reject=%d,"\
                        "ftq=%f,cycletime=%f,time='%s',eun='%s',lastcycle=%f,pano=%d,"\
                        "maxcycle=%f,mincycle=%f,overcycle=%d,overcycle_positive_three=%d,overcycle_negative_three=%d WHERE station = '%s'"\
                        %(good,reject,ftq,cycle,time,eun,lastCycle,pano,maxcycle,mincycle,overcycle,overcycle_positive,overcycle_negative,station)

        if station in others:
            if other not in [None,'']:
                other = json.loads(other)
                b = {}
                for bb in other:
                    # bb = others[station] + self.keys[bb] + ':' + other[bb] + '\n'
                    b[bb] = other[bb][0]
                b = json.dumps({others[station]:b})

                sqlfun="UPDATE assembly.fine_as SET count_good=%d,count_reject=%d,"\
                        "ftq=%f,cycletime=%f,time='%s',eun='%s',lastcycle=%f,pano=%d,"\
                        "maxcycle=%f,mincycle=%f,overcycle=%d,keypara = '%s',overcycle_positive_three=%d,overcycle_negative_three=%d WHERE station = '%s'"\
                        %(good,reject,ftq,cycle,time,eun,lastCycle,pano,maxcycle,mincycle,overcycle,b,overcycle_positive,overcycle_negative,station)
                cur.execute(sqlfun)
            elif station in ['1210S3','2130A-2']:
                if eun[3:5] not in ['RA','CS','DF','RE','RC','RF','SA','SB','TB','BH']:
                    sqlfun="UPDATE assembly.fine_as SET count_good=%d,count_reject=%d,"\
                        "ftq=%f,cycletime=%f,time='%s',eun='%s',lastcycle=%f,pano=%d,"\
                        "maxcycle=%f,mincycle=%f,overcycle=%d,overcycle_positive_three=%d,overcycle_negative_three=%d WHERE station = '%s'"\
                        %(good,reject,ftq,cycle,time,eun,lastCycle,pano,maxcycle,mincycle,overcycle,overcycle_positive,overcycle_negative,station)
                    cur.execute(sqlfun)

            elif station in ['1210S1','2130A-1']:
                if eun[3:5] not in ['RZ','AZ','BW','SM']:
                    sqlfun="UPDATE assembly.fine_as SET count_good=%d,count_reject=%d,"\
                        "ftq=%f,cycletime=%f,time='%s',eun='%s',lastcycle=%f,pano=%d,"\
                        "maxcycle=%f,mincycle=%f,overcycle=%d,overcycle_positive_three=%d,overcycle_negative_three=%d WHERE station = '%s'"\
                        %(good,reject,ftq,cycle,time,eun,lastCycle,pano,maxcycle,mincycle,overcycle,overcycle_positive,overcycle_negative,station)
                    cur.execute(sqlfun)
            
            else:
                sqlfun="UPDATE assembly.fine_as SET count_good=%d,count_reject=%d,"\
                        "ftq=%f,cycletime=%f,time='%s',eun='%s',lastcycle=%f,pano=%d,"\
                        "maxcycle=%f,mincycle=%f,overcycle=%d,overcycle_positive_three=%d,overcycle_negative_three=%d WHERE station = '%s'"\
                        %(good,reject,ftq,cycle,time,eun,lastCycle,pano,maxcycle,mincycle,overcycle,overcycle_positive,overcycle_negative,station)
                cur.execute(sqlfun)


        else:
            if station == '2050A-2':
                if eun[3:5] == 'TB':
                    sqlfun="UPDATE assembly.fine_as SET count_good=%d,count_reject=%d,"\
                        "ftq=%f,cycletime=%f,time='%s',eun='%s',lastcycle=%f,pano=%d,"\
                        "maxcycle=%f,mincycle=%f,overcycle=%d,overcycle_positive_three=%d,overcycle_negative_three=%d WHERE station = '%s'"\
                        %(good,reject,ftq,cycle,time,eun,lastCycle,pano,maxcycle,mincycle,overcycle,overcycle_positive,overcycle_negative,station)
                    cur.execute(sqlfun)
            else:
                sqlfun="UPDATE assembly.fine_as SET count_good=%d,count_reject=%d,"\
                        "ftq=%f,cycletime=%f,time='%s',eun='%s',lastcycle=%f,pano=%d,"\
                        "maxcycle=%f,mincycle=%f,overcycle=%d,overcycle_positive_three=%d,overcycle_negative_three=%d WHERE station = '%s'"\
                        %(good,reject,ftq,cycle,time,eun,lastCycle,pano,maxcycle,mincycle,overcycle,overcycle_positive,overcycle_negative,station)
                cur.execute(sqlfun)

        cnx.commit()
        cur.close()
        cnx.close()
    except Exception as e:
        print(e)

def getAsHourOut():
    try:
        curdate = datetime.datetime.now().strftime("%Y-%m-%d")
        curhour = int(datetime.datetime.now().strftime("%H"))
        curmin = int(datetime.datetime.now().strftime("%M"))
        yesterday = (datetime.datetime.now() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d")
        
        cnx=pymysql.connect('127.0.0.1','CHUAN','password',"assembly" )
        cur=cnx.cursor()
        sqlfun = 'select shift from assembly.shift_hour order by id desc limit 1'
        cur.execute(sqlfun)
        shiftHour = cur.fetchall()[0][0]

        if int(shiftHour) == shiftHour:
            shiftHour = int(shiftHour)

            if curhour >= 8:
                sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                        " order by output_perhour_id desc limit 1"%curdate
                cur.execute(sqlfun)
                fetchData = cur.fetchall()[0]
                
                if curhour < shiftHour:
                    sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                            " order by output_perhour_id desc limit 1"%yesterday
                    cur.execute(sqlfun)
                else:
                    sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                            " order by output_perhour_id desc limit 1"%curdate
                    cur.execute(sqlfun)
                fetchDataYesterday = cur.fetchall()[0]
            else:
                sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                        " order by output_perhour_id desc limit 1"%yesterday
                cur.execute(sqlfun)
                fetchData = cur.fetchall()[0]

                sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                            " order by output_perhour_id desc limit 1"%curdate
                cur.execute(sqlfun)
                fetchDataYesterday = cur.fetchall()[0]

            cnx.commit()
            cur.close()
            cnx.close()


        
            dataLoopAFirstTmp = [0] + list(fetchData[2:(shiftHour-6)])
            dataLoopBFirstTmp = [0] + list(fetchData[27:(shiftHour+19)])
            if curhour >= 8:
                if curhour < shiftHour:
                    dataLoopASecondTmp = list(fetchDataYesterday[(shiftHour-6-1):18]) + list(fetchData[18:24]) + list(fetchData[25:27])
                    dataLoopBSecondTmp = list(fetchDataYesterday[(shiftHour+19-1):43]) + list(fetchData[43:49]) + list(fetchData[50:52])
                else:
                    dataLoopASecondTmp = list(fetchDataYesterday[(shiftHour-6-1):18]) + ((shiftHour-16)*2) * [0]
                    dataLoopBSecondTmp = list(fetchDataYesterday[(shiftHour+19-1):43]) + ((shiftHour-16)*2) * [0]
            else:
                dataLoopASecondTmp = list(fetchData[(shiftHour-6-1):18])  + list(fetchDataYesterday[18:24]) + list(fetchDataYesterday[25:27])
                dataLoopBSecondTmp = list(fetchData[(shiftHour+19-1):43]) + list(fetchDataYesterday[43:49]) + list(fetchDataYesterday[50:52])

            
            dataLoopAFirst = []
            dataLoopBFirst = []
            dataLoopASecond = []
            dataLoopBSecond = []
            
            for i in range(len(dataLoopAFirstTmp)-1):
                if dataLoopAFirstTmp[i+1] != 0 and dataLoopAFirstTmp[i] != 0:
                    tmp = dataLoopAFirstTmp[i+1] - dataLoopAFirstTmp[i]
                    if tmp >= 0:
                        dataLoopAFirst.append(tmp)
                    else:
                        dataLoopAFirst.append(dataLoopAFirstTmp[i+1])
                elif dataLoopAFirstTmp[i] == 0 and dataLoopAFirstTmp[i+1] != 0:
                    dataLoopAFirst.append(dataLoopAFirstTmp[i+1])
                else:
                    dataLoopAFirst.append(0)
                    
                if dataLoopBFirstTmp[i+1] != 0 and dataLoopBFirstTmp[i] != 0:
                    tmp = dataLoopBFirstTmp[i+1] - dataLoopBFirstTmp[i]
                    if tmp >= 0:
                        dataLoopBFirst.append(tmp)
                    else:
                        dataLoopBFirst.append(dataLoopBFirstTmp[i+1])
                elif dataLoopBFirstTmp[i] == 0 and dataLoopBFirstTmp[i+1] != 0:
                    dataLoopBFirst.append(dataLoopBFirstTmp[i+1])
                else:
                    dataLoopBFirst.append(0)
                    
            for i in range(len(dataLoopASecondTmp)-1):
                if dataLoopASecondTmp[i+1] != 0 and dataLoopASecondTmp[i] != 0:
                    tmp = dataLoopASecondTmp[i+1] - dataLoopASecondTmp[i]
                    if tmp >= 0:
                        dataLoopASecond.append(tmp)
                    else:
                        dataLoopASecond.append(dataLoopASecondTmp[i+1])
                elif dataLoopASecondTmp[i] == 0 and dataLoopASecondTmp[i+1] != 0:
                    dataLoopASecond.append(dataLoopASecondTmp[i+1])
                else:
                    dataLoopASecond.append(0)
                    
                if dataLoopBSecondTmp[i+1] != 0 and dataLoopBSecondTmp[i] != 0:
                    tmp = dataLoopBSecondTmp[i+1] - dataLoopBSecondTmp[i]
                    if tmp >= 0:
                        dataLoopBSecond.append(tmp)
                    else:
                        dataLoopBSecond.append(dataLoopBSecondTmp[i+1])
                elif dataLoopBSecondTmp[i] == 0 and dataLoopBSecondTmp[i+1] != 0:
                    dataLoopBSecond.append(dataLoopBSecondTmp[i+1])
                else:
                    dataLoopBSecond.append(0)

            dataLoopASecond = dataLoopASecond[:(shiftHour-8)]    
            dataLoopBSecond = dataLoopBSecond[:(shiftHour-8)]

        else:

            curdate = datetime.datetime.now().strftime("%Y-%m-%d")
            curhour = int(datetime.datetime.now().strftime("%H"))
            curmin = int(datetime.datetime.now().strftime("%M"))
            yesterday = (datetime.datetime.now() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d")
            
            cnx=pymysql.connect('127.0.0.1','CHUAN','password',"assembly" )
            cur=cnx.cursor()
            sqlfun = 'select shift from assembly.shift_hour order by id desc limit 1'
            cur.execute(sqlfun)
            shiftHour = cur.fetchall()[0][0]

            loopa_append = 0
            loopb_append = 0
            
            # curhour = 22
            # shiftHour = 19.5

            if curhour >= 8:
                sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                        " order by output_perhour_id desc limit 1"%curdate
                cur.execute(sqlfun)
                fetchData = cur.fetchall()[0]
                
                if curhour < shiftHour:
                    sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                            " order by output_perhour_id desc limit 1"%yesterday
                    cur.execute(sqlfun)
                    fetchDataYesterday = cur.fetchall()[0]
                    loopa_append = fetchData[52]
                    loopb_append = fetchData[53]
                else:
                    loopa_append = fetchData[52]
                    loopb_append = fetchData[53]
        ##            sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
        ##                     " order by output_perhour_id desc limit 1"%curdate
        ##            cur.execute(sqlfun)
                    fetchDataYesterday = fetchData
            else:
                sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                        " order by output_perhour_id desc limit 1"%yesterday
                cur.execute(sqlfun)
                fetchData = cur.fetchall()[0]
                loopa_append = fetchData[52]
                loopb_append = fetchData[53]

                sqlfun = "select * from assembly.output_perhour where output_perhour_date='%s'"\
                            " order by output_perhour_id desc limit 1"%curdate
                cur.execute(sqlfun)
                fetchDataYesterday = cur.fetchall()[0]

            cnx.commit()
            cur.close()
            cnx.close()
            print('######',loopa_append,loopb_append,)
        ##    print(fetchData)
        ##    print(fetchDataYesterday)



            # if curmin < ceil(60*(shiftHour - int(shiftHour))):

            dataLoopAFirstTmp = [0] + list(fetchData[2:(int(shiftHour)-6)]) + [loopa_append]
            dataLoopBFirstTmp = [0] + list(fetchData[27:(int(shiftHour)+19)]) + [loopb_append]
            print(len(dataLoopAFirstTmp),dataLoopAFirstTmp)
            print(len(dataLoopBFirstTmp),dataLoopBFirstTmp)



            if curhour >= 8:
                if curhour+curmin/60 < shiftHour:
                    dataLoopASecondTmp = list(fetchDataYesterday[(int(shiftHour)-6):18]) + list(fetchData[18:24]) + list(fetchData[25:27])
                    dataLoopBSecondTmp = list(fetchDataYesterday[int(shiftHour+19):43]) + list(fetchData[43:49]) + list(fetchData[50:52])
                    
                else:
                    dataLoopASecondTmp = list(fetchData[(int(shiftHour)-6):18]) + [0]*10#((int(shiftHour*2-int(shiftHour))-16)*2) * [0]
                    dataLoopBSecondTmp = list(fetchData[(int(shiftHour)+19):43]) + [0]*10#((int(shiftHour*2-int(shiftHour))-16)*2) * [0]
##                    print('################# hahhahahaah')
            else:
                dataLoopASecondTmp = list(fetchData[(int(shiftHour)-6):18])  + list(fetchDataYesterday[18:24]) + list(fetchDataYesterday[25:27])
                dataLoopBSecondTmp = list(fetchData[(int(shiftHour)+19):43]) + list(fetchDataYesterday[43:49]) + list(fetchDataYesterday[50:52])

            print(dataLoopASecondTmp[0])
            if dataLoopASecondTmp[0] > dataLoopAFirstTmp[-1] and dataLoopAFirstTmp[-1]>100:
                dataLoopASecondTmp.insert(0,dataLoopASecondTmp[0] - dataLoopAFirstTmp[-1])
                dataLoopBSecondTmp.insert(0,dataLoopBSecondTmp[0] - dataLoopBFirstTmp[-1])
            else:            
                dataLoopASecondTmp.insert(0,0)
                dataLoopBSecondTmp.insert(0,0)

            print(len(dataLoopASecondTmp),dataLoopASecondTmp)
            print(len(dataLoopBSecondTmp),dataLoopBSecondTmp)
            
            dataLoopAFirst = []
            dataLoopBFirst = []
            dataLoopASecond = []
            dataLoopBSecond = []
            
            # for i in range(len(dataLoopAFirstTmp)-1):
            for i in range(len(dataLoopAFirstTmp)-1):
                if dataLoopAFirstTmp[i+1] != 0 and dataLoopAFirstTmp[i] != 0:
                    tmp = dataLoopAFirstTmp[i+1] - dataLoopAFirstTmp[i]
                    if tmp >= 0:
                        dataLoopAFirst.append(tmp)
                    else:
                        dataLoopAFirst.append(dataLoopAFirstTmp[i+1])
                elif dataLoopAFirstTmp[i] == 0 and dataLoopAFirstTmp[i+1] != 0:
                    dataLoopAFirst.append(dataLoopAFirstTmp[i+1])
                else:
                    dataLoopAFirst.append(0)
                    
                if dataLoopBFirstTmp[i+1] != 0 and dataLoopBFirstTmp[i] != 0:
                    tmp = dataLoopBFirstTmp[i+1] - dataLoopBFirstTmp[i]
                    if tmp >= 0:
                        dataLoopBFirst.append(tmp)
                    else:
                        dataLoopBFirst.append(dataLoopBFirstTmp[i+1])
                elif dataLoopBFirstTmp[i] == 0 and dataLoopBFirstTmp[i+1] != 0:
                    dataLoopBFirst.append(dataLoopBFirstTmp[i+1])
                else:
                    dataLoopBFirst.append(0)
                    
            # for i in range(len(dataLoopASecondTmp)-1):
            for i in range(12):#len(dataLoopASecondTmp)-1):
                if dataLoopASecondTmp[i+1] != 0 and dataLoopASecondTmp[i] != 0:
                    tmp = dataLoopASecondTmp[i+1] - dataLoopASecondTmp[i]
                    if tmp >= 0:
                        dataLoopASecond.append(tmp)
                    else:
                        dataLoopASecond.append(dataLoopASecondTmp[i+1])
                elif dataLoopASecondTmp[i] == 0 and dataLoopASecondTmp[i+1] != 0:
                    dataLoopASecond.append(dataLoopASecondTmp[i+1])
                else:
                    dataLoopASecond.append(0)
                    
                if dataLoopBSecondTmp[i+1] != 0 and dataLoopBSecondTmp[i] != 0:
                    tmp = dataLoopBSecondTmp[i+1] - dataLoopBSecondTmp[i]
                    if tmp >= 0:
                        dataLoopBSecond.append(tmp)
                    else:
                        dataLoopBSecond.append(dataLoopBSecondTmp[i+1])
                elif dataLoopBSecondTmp[i] == 0 and dataLoopBSecondTmp[i+1] != 0:
                    dataLoopBSecond.append(dataLoopBSecondTmp[i+1])
                else:
                    dataLoopBSecond.append(0)


        print('LOOPA 白班:',dataLoopAFirst)
        print('LOOPA 中班:',dataLoopASecond)
        print('LOOPB 白班:',dataLoopBFirst)
        print('LOOPB 中班:',dataLoopBSecond)

        return dataLoopAFirst,dataLoopASecond,dataLoopBFirst,dataLoopBSecond
    except Exception as e:
        print(e)

def updateAsPerhourOut():
    LoopAFirst = 0
    LoopASecond = 0
    LoopBFirst = 0
    LoopBSecond = 0
    try:
        data = list(getAsHourOut())
        for i in range(len(data)):
            data[i] = data[i] + (12 - len(data[i])) * [0]
        LoopAFirst,LoopASecond,LoopBFirst,LoopBSecond = data
        loops = ['A','A','B','B']
        shifts = ['白','中','白','中']

        curdate = datetime.datetime.now().strftime("%Y-%m-%d")
        curhour = int(datetime.datetime.now().strftime("%H"))
        yesterday = (datetime.datetime.now() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d")
        
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
        cur=cnx.cursor()
        sqlfun = 'select shift from assembly.shift_hour order by id desc limit 1'
        cur.execute(sqlfun)
        shiftHour = cur.fetchall()[0][0]

        if curhour >= 8:
            if curhour < shiftHour:
                date = [curdate,yesterday,curdate,yesterday]
            else:
                date = [curdate]*4
            dateup = curdate
        else:
            date = [yesterday,curdate,yesterday,curdate]
            dateup = yesterday
        
        for i in range(4):
            sf1 = "UPDATE assembly.fine_as_count SET date = '%s',"%date[i]
            sf2 = ''
            sf2tmp = []
            for j in range(1,13):
                sf2tmp.append("hour_%d = %d"%(j,data[i][j-1]))
            sf2 = ','.join(sf2tmp)
            sf3 = " where (`loop`='%s' and `shift`='%s' and `date_filter`='%s')"%(loops[i],shifts[i],dateup)
            sqlfun = sf1 + sf2 + sf3

            cur.execute(sqlfun)

        for i in range(4):
            for j in range(12):
                hour = 'hour_' + str(j+1)
                sqlfun = "UPDATE assembly.fine_as_count_vertical SET date = '%s',"\
                         "count=%d where (`date_filter`='%s' and `loop`='%s' and `shift`='%s' and `hour`='%s');"\
                             %(date[i],data[i][j],dateup,loops[i],shifts[i],hour)
                cur.execute(sqlfun)
                
        cnx.commit()
        cur.close()
        cnx.close()

        return LoopAFirst,LoopASecond,LoopBFirst,LoopBSecond
    
    except Exception as e:
        print('12312321312312312',str(e))

def insertAsCount():
    try:
        curdate = datetime.datetime.now().strftime("%Y-%m-%d")
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
        cur=cnx.cursor()
        sqlfun = 'select date_filter from assembly.fine_as_count order by id desc limit 1'
        cur.execute(sqlfun)
        lastDate = cur.fetchall()[0][0]

        if lastDate.strftime("%Y-%m-%d") != curdate:
            sqlfun = 'select * from assembly.fine_as_count_default'
            cur.execute(sqlfun)
            asCountDefault = cur.fetchall()

            for ac in asCountDefault:
                loop = ac[2]
                shift = ac[3]
                sqlfun = "INSERT INTO `assembly`.`fine_as_count` (`loop`, `shift`, `date_filter`) "\
                         "VALUES ('%s','%s','%s');"%(loop,shift,curdate)
                cur.execute(sqlfun)
        cnx.commit()
        cur.close()
        cnx.close()
    except:
        pass


def insertAsCountVertical():
    try:
        curdate = datetime.datetime.now().strftime("%Y-%m-%d")
        cnx=pymysql.connect('127.0.0.1','root','12345678',"assembly" )
        cur=cnx.cursor()
        sqlfun = 'select date_filter from assembly.fine_as_count_vertical order by id desc limit 1'
        cur.execute(sqlfun)
        lastDate = cur.fetchall()[0][0]

        if lastDate.strftime("%Y-%m-%d") != curdate:
            sqlfun = 'select * from assembly.fine_as_count_vertical_default'
            cur.execute(sqlfun)
            asCountDefault = cur.fetchall()
            for ac in asCountDefault:
                loop = ac[3]
                shift = ac[2]
                hour = ac[4]
                sqlfun = "INSERT INTO `assembly`.`fine_as_count_vertical` (`loop`, `shift`, `hour`, `date_filter`) "\
                         "VALUES ('%s','%s','%s','%s');"%(loop,shift,hour,curdate)
                cur.execute(sqlfun)
                cnx.commit()
        
        cur.close()
        cnx.close()
    except:
        pass
def getStaRecordTarget(staRecordQueue,errorQueue,staStatus,stasRflatten):
    lastEUN = {}
    lastCount = {}
    lastPa = {}
    lastXXX = {}
    for sta in stasRflatten:
        lastEUN[sta] = ''
        lastCount[sta] = 0
        lastPa[sta] = 0
        lastXXX[sta] = ''
    
    # N15 = ['RA','CS','DF','RE','RC','RF','SA','SB','TB','BH','UV','UW','UX','UY','UZ']
    ET = getEngineTypes()
    # N12 = list(ET[0]) + list(ET[1])
    N15 = list(ET[2]) + list(ET[3])

    st = time.time()
        
    while 1:
        for sta in stasRflatten:
            try:
                if sta in ['1445R','2515R']:
                    if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] \
                        or (staStatus[sta]['rejectpiece'] != lastCount[sta] and staStatus[sta]['palletno'] == lastPa[sta]):
                        staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                                ]
                            )

                        lastEUN[sta]=staStatus[sta]['EUN']
                        lastCount[sta] = staStatus[sta]['rejectpiece']
                        lastPa[sta] = staStatus[sta]['palletno']

                elif sta in ['1010M','1060M','1170M']:
                    if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20\
                       or (staStatus[sta]['EUN'] == lastEUN[sta] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20):
                        staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                            ]
                        )

                        lastEUN[sta] = staStatus[sta]['EUN']
                        lastXXX[sta] = staStatus[sta]['other']
                elif sta == '3090A':
                    if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20\
                       or (staStatus[sta]['EUN'] == lastEUN[sta] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20):

                        staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                            ]
                        )
                        lastEUN[sta] = staStatus[sta]['EUN']
                        lastXXX[sta] = staStatus[sta]['other']
                        
                elif sta == '3100A':
                    if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20\
                       or (staStatus[sta]['EUN'] == lastEUN[sta] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20):

                        staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                            ]
                        )
                        lastEUN[sta] = staStatus[sta]['EUN']
                        lastXXX[sta] = staStatus[sta]['other']

                elif sta == '1210S3':
                    if staStatus[sta]['EUN'][3:5] in N15:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20\
                        or (staStatus[sta]['EUN'] == lastEUN[sta] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20):
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece'],
                                    staStatus[sta]['other']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']
                            lastXXX[sta] = staStatus[sta]['other']
                    else:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece'],
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']

                elif sta == '1210S1':
                    if staStatus[sta]['EUN'][3:5] not in N15:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20\
                        or (staStatus[sta]['EUN'] == lastEUN[sta] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20):

                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece'],
                                    staStatus[sta]['other']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']
                            lastXXX[sta] = staStatus[sta]['other']
                    else:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece'],
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']

                elif sta in '2350A':
                    if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and len(staStatus[sta]['other'])>10:
                        staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                            ]
                        )
                        lastEUN[sta] = staStatus[sta]['EUN']
                
                elif sta in '2050A-2':
                    # if staStatus[sta]['EUN'][3:5] in N15:
                    if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and len(staStatus[sta]['other'])>10:
                        staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                            ]
                        )
                        lastEUN[sta] = staStatus[sta]['EUN']
                    elif staStatus[sta]['EUN'][3:5] == 'TB':
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']

                elif sta == '2170M':
                    if staStatus[sta]['EUN'][3:5] in N12:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]and len(staStatus[sta]['other'])>10:
                            staRecordQueue.put(
                                [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                                ]
                                )
                            lastEUN[sta] = staStatus[sta]['EUN']
                    else:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']

                elif sta == '2340M':
                    if staStatus[sta]['EUN'][3:5] in N12:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]and len(staStatus[sta]['other'])>10 and \
                            staStatus[sta]['other'] != lastXXX[sta]:
                            staRecordQueue.put(
                                [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                                ]
                                )
                            lastEUN[sta] = staStatus[sta]['EUN']
                            lastXXX[sta] = staStatus[sta]['other']
                    else:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']
                
                elif sta == '1261M':
                    if staStatus[sta]['EUN'][3:5] in ['RE','TB']:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]and len(staStatus[sta]['other'])>10:
                            staRecordQueue.put(
                                [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                                ]
                                )
                            lastEUN[sta] = staStatus[sta]['EUN']
                    else:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']

                
                elif sta == '3060A1':
                    if staStatus[sta]['EUN'][:2] in N15:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]and len(staStatus[sta]['other'])>10:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece'],
                                    staStatus[sta]['other']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']
                    else:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']
                
                elif  sta == '2470M':
                    if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>14\
                       or (staStatus[sta]['EUN'] == lastEUN[sta] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>14):
                        staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece'],
                                staStatus[sta]['other']
                            ]
                        )

                        lastEUN[sta] = staStatus[sta]['EUN']
                        lastXXX[sta] = staStatus[sta]['other']

                elif sta == '2130A-1':
                    # print('@@@@@@@@@@@@@@@',time.time()-st)
                    # st = time.time()
                    if staStatus[sta]['EUN'][3:5] in N15:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece']
                            ]
                            )
                            lastEUN[sta]=staStatus[sta]['EUN']
                    else:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20\
                            or (staStatus[sta]['EUN'] == lastEUN[sta] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20):
                        # if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece'],
                                    staStatus[sta]['other']
                                ]
                            )

                            lastEUN[sta] = staStatus[sta]['EUN']
                            lastXXX[sta] = staStatus[sta]['other']

                elif sta == '2130A-2':
                    if staStatus[sta]['EUN'][3:5] in N15:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20\
                            or (staStatus[sta]['EUN'] == lastEUN[sta] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20):
                        # print('$$$$$$$$$$$$$$$$$',len(staStatus[sta]['other']),staStatus[sta]['other'])
                        # if staStatus[sta]['EUN'] not in ['',lastEUN[sta]] and staStatus[sta]['other'] != lastXXX[sta] and len(staStatus[sta]['other'])>20:
                            staRecordQueue.put(
                                [
                                    staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                    sta, 
                                    staStatus[sta]['palletno'],
                                    staStatus[sta]['lastcycle'], 
                                    staStatus[sta]['currentcycle'],
                                    staStatus[sta]['goodpiece'],
                                    staStatus[sta]['rejectpiece'],
                                    staStatus[sta]['other']
                                ]
                            )
                            lastEUN[sta] = staStatus[sta]['EUN']
                            lastXXX[sta] = staStatus[sta]['other']
                    else:
                        if staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                            staRecordQueue.put(
                            [
                                staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                                sta, 
                                staStatus[sta]['palletno'],
                                staStatus[sta]['lastcycle'], 
                                staStatus[sta]['currentcycle'],
                                staStatus[sta]['goodpiece'],
                                staStatus[sta]['rejectpiece']
                            ]
                            )
                            lastEUN[sta]=staStatus[sta]['EUN']
                    

                elif staStatus[sta]['EUN'] not in ['',lastEUN[sta]]:
                    staRecordQueue.put(
                        [
                            staStatus[sta]['EUN']+'_T_'+str(staStatus[sta]['buildable']),
                            sta, 
                            staStatus[sta]['palletno'],
                            staStatus[sta]['lastcycle'], 
                            staStatus[sta]['currentcycle'],
                            staStatus[sta]['goodpiece'],
                            staStatus[sta]['rejectpiece']
                        ]
                    )

                    lastEUN[sta]=staStatus[sta]['EUN']

            except BaseException as e:
                print(e)
                text = 'get station record information error,station: ' + sta + 'errorcode: ' + str(e)
                errorQueue.put(['err',text])
    

def staRecordP(staRecordQueue):
    while 1:
        if staRecordQueue.qsize() > 0:
            for i in range(staRecordQueue.qsize()):
                tmp = staRecordQueue.get()
                # if tmp[1] == '2130A-1':
                #     print('2130A-1',len(tmp),tmp[0])
                # if tmp[1] == '2130A-2':
                #     print('2130A-2',len(tmp),tmp[0])
                # if tmp[1] in ['1445R','2515R','1010M','1060M','1170M']:

                if len(tmp) == 8:
                    staRecord(
                        tmp[0],
                        tmp[1],
                        tmp[2],
                        tmp[3],
                        tmp[4],
                        tmp[5],
                        tmp[6],
                        tmp[7],
                        )
                else:
                    staRecord(
                        tmp[0],
                        tmp[1],
                        tmp[2],
                        tmp[3],
                        tmp[4],
                        tmp[5],
                        tmp[6]
                        )
        else:
            time.sleep(1)

def andon_handle(staSequence, q):
    # 记录员工拉维修、班长暗灯
    def findloop(sta):
        if sta == '2480M':
            loop = 'R'
        elif sta[0] in '134':
            loop = 'A'
        else:
            loop = 'B'
        return loop

    def findteam(sta):
        team = ''
        if sta == '2480M':
            team = 1
        else:
            sta = int(sta[:4])
            if (sta > 1000 and sta < 1100) or (sta > 4000 and sta < 4600):
                team = 1
            elif (sta > 1099 and sta < 1171) or (sta > 3000 and sta < 3130):
                team = 2
            elif (sta > 1179 and sta < 1299):
                team = 3
            elif sta > 1299 and sta < 1431:
                team = 4
            elif sta > 2000 and sta < 2199:
                team = 1
            elif (sta > 2229 and sta < 2331) or (sta > 5000 and sta < 5041):
                team = 2
            elif (sta > 2339 and sta < 2491) or (sta > 6000):
                team = 3

        return team

    def insertAndonData(andon_type, sta):
        loop = findloop(sta)
        team = findteam(sta)
        cnx=pymysql.connect('10.64.34.11','root','Sgmw5050',"assembly" )
        cur=cnx.cursor()
        sqlfun = "INSERT INTO `assembly`.`andon_his_andon_data` (`station`, `type`, `starttime`,`loop`,`team`) "\
            "VALUES ('%s', '%s', '%s', '%s', '%s');"%(sta, andon_type, datetime.datetime.now(),loop,team)
        cur.execute(sqlfun)
        cnx.commit()
        cur.close()
        cnx.close()

    

    def updateAndonData(andon_type, sta):
        # print("55555555555555555555555555  updateAndonData,", andon_type, sta)
        cnx=pymysql.connect('10.64.34.11','root','Sgmw5050',"assembly" )
        cur=cnx.cursor()
        sqlfun = "select id,starttime from assembly.andon_his_andon_data where station='%s' and type='%s'"\
             " order by id desc limit 1;"%(sta,andon_type)
        cur.execute(sqlfun)
        data = cur.fetchall()
        id = data[0][0]
        st = data[0][1]
        et = datetime.datetime.now()
        dur = (et-st).seconds

        sqlfun = "UPDATE `assembly`.`andon_his_andon_data` SET  `endtime` = '%s',"\
            " lastModifiedTime='%s',dur='%s' WHERE (`id` = '%s') order by id desc limit 1" \
                %(et, et, dur, id)
        cur.execute(sqlfun)
        cnx.commit()
        cur.close()
        cnx.close()

    last_lay = '-' * 300
    while True:
        while q.qsize() > 0:
            lay = q.get()
            for i in range(len(lay)):
                if staSequence[i] == '1055M':
                    pass
                else:
                    if lay[i] == '3' and last_lay[i] != '3':
                        insertAndonData('mt',staSequence[i])

                    elif lay[i] == '4' and last_lay[i] != '4':
                        insertAndonData('tl',staSequence[i])

                    if lay[i] != '3' and last_lay[i] == '3':
                        updateAndonData('mt',staSequence[i])

                    elif lay[i] != '4' and last_lay[i] == '4':
                        updateAndonData('tl',staSequence[i])

            last_lay = lay
            
                    
        time.sleep(2)



class errorInformation(object):
    def __init__(self):
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.INFO)
        logfile = 'default.log'
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        fh = handlers.TimedRotatingFileHandler(filename='logs/' + logfile, interval=1, when='D', encoding='utf-8')
        def namer(filename):
            return 'logs/' + filename.split('.log.')[1]
        fh.namer = namer
        fh.suffix = "%Y%m%d.log"
        fh.setLevel(logging.DEBUG) 
        formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)
        self.logger.addHandler(fh)
        self.logger.addHandler(ch)
    
    def logInfo(self,text):
        self.logger.info(text)

    def logError(self,text):
        self.logger.error(text)



if __name__=="__main__":

    global LoopAFirst,LoopBFirst,LoopASecond,LoopBSecond
    

    ips,stasR,stasP,stasB,stasPalletno,errorStations,errorIDs,ns,errorListVisible=initConfig()
    for errorID,ip in zip(errorIDs,ips):
        print(errorID,ip)

    # 2023-05-25  '2380P','2390M' 更换为 '2390M', '2400M'
    staSequence = ['1006L','TT01','1008#1','1008#2','1008#3','1010P1','1010P2','1010M',
                    '1020P','1020A','1030P','1030A','1035B','1040M','1050P','1050M','1055M','1060M',
                    '1070P','1070M','1075B','1080P','1080A','1090A','1095A','1096U','1096L','TT02',
                    '1100P','1100M','1110P','1110A','1115B','1120P','1120A','1126U','1126L','TT03',
                    '1140P1','1140P2','1140M','1150P','1150M','1160P','1160A','1165P','1165B','1170P',
                    '1170M','1180M','1195B','1190P','1196U','1196L','1190A','1210S3','1210S1','1210S2',
                    '1220P1','1220P2','1220M','1230P','1230M','1235B','1240P','1240A','1245B','1250P',
                    '1250M','1260P','1260M','1261P','1261M','1270P','1270M','1275A','1280M','1290P',
                    '1290A','1295B','1300M','1310P','1310A','1315P','1315#1','1315B','1320P','1320A',
                    '1330P','1330M','1340P','1340M','1350-1P','1350A-1','1350-2P','1350A-2','1355B',
                    '1360P','1360M','1368#1','1368#2','1368B','1370P','1370A','1380P','1380M','1390P',
                    '1390M','1400-1P','1400A-1','1400-2P','1400A-2','1405B','1410P','1410M','1420P',
                    '1420M','1430P','1430M-1','1265#1','1265#2','1265#3','1265#4','1265#5','1265#6',
                    '1265#7','1265#8','1265R','1430-2P#2','1430-2','1430-2P#1','2006U','2006L','TT01',
                    '2010P1','2010P2','2010P3','2010M','2020P','2020M','2030P','2030M','2040P','2040M',
                    '2050-1P','2050A-1','2050-2P','2050A-2','2055B','2060M','2070M','2080M','2090M',
                    '2100M','2110M','2120M','2130-1P','2130A-1','2130-2P','2130A-2','2140P','2140M',
                    '2150P','2150M','2155B','2160P','2160A','2170P','2170M','2180P','2180A','2185B',
                    '2190P','2190M','2196U','2196L','TT05','TT06#1','TT06#2','TT06#3','TT06#4','TT06#5',
                    'TT06(2210)','TT07#1','TT07#2','TT07#3','TT07(2220)','2230P','2230M','TT08#0',
                    'TT08#1','TT08#2','2236U','2236L','TT08','2240P','2240M','2250P','2250M','2255B',
                    '2260A','2270M','2280M','2290P','2290M','2300P','2300M','2310P','2310M','2315B',
                    '2320P','2320A','2330P','2340M','2350P','2350A','2355P','2355B','2356U','2356L',
                    'TT09','2360M','2370P','2370A','2375B','2390M','2400M','2410M','2420P','2420M',
                    '2430M','2440M','2450M','2460P','2460M','2470P','2470M','2475P','2475A','2476U',
                    '2476L','TT10','2480P','2480M','2490P','2490M','2500P','2500M','2505P','2505#1',
                    '2505#2','2505B','2145#1','2145#2','2145#3','2145#4','2145#5','2145#6','2145#7',
                    '2145#8','2145R']

    # staSequence = ['1006L','TT01','1008#1','1008#2','1008#3','1010P1','1010P2','1010M',
    #             '1020P','1020A','1030P','1030A','1035B','1040M','1050P','1050M','1055M','1060M',
    #             '1070P','1070M','1075B','1080P','1080A','1090A','1095A','1096U','1096L','TT02',
    #             '1100P','1100M','1110P','1110A','1115B','1120P','1120A','1126U','1126L','TT03',
    #             '1140P1','1140P2','1140M','1150P','1150M','1160P','1160A','1165P','1165B','1170P',
    #             '1170M','1180M','1195B','1190P','1196U','1196L','1190A','1210S3','1210S1','1210S2',
    #             '1220P1','1220P2','1220M','1230P','1230M','1235B','1240P','1240A','1245B','1250P',
    #             '1250M','1260P','1260M','1261P','1261M','1270P','1270M','1275A','1280M','1290P',
    #             '1290A','1295B','1300M','1310P','1310A','1315P','1315#1','1315B','1320P','1320A',
    #             '1330P','1330M','1340P','1340M','1350-1P','1350A-1','1350-2P','1350A-2','1355B',
    #             '1360P','1360M','1368#1','1368#2','1368B','1370P','1370A','1380P','1380M','1390P',
    #             '1390M','1400-1P','1400A-1','1400-2P','1400A-2','1405B','1410P','1410M','1420P',
    #             '1420M','1430P','1430M-1','1265#1','1265#2','1265#3','1265#4','1265#5','1265#6',
    #             '1265#7','1265#8','1265R','1430-2P#2','1430-2','1430-2P#1','2006U','2006L','TT01',
    #             '2010P1','2010P2','2010P3','2010M','2020P','2020M','2030P','2030M','2040P','2040M',
    #             '2050-1P','2050A-1','2050-2P','2050A-2','2055B','2060M','2070M','2080M','2090M',
    #             '2100M','2110M','2120M','2130-1P','2130A-1','2130-2P','2130A-2','2140P','2140M',
    #             '2150P','2150M','2155B','2160P','2160A','2170P','2170M','2180P','2180A','2185B',
    #             '2190P','2190M','2196U','2196L','TT05','TT06#1','TT06#2','TT06#3','TT06#4','TT06#5',
    #             'TT06(2210)','TT07#1','TT07#2','TT07#3','TT07(2220)','2230P','2230M','TT08#0',
    #             'TT08#1','TT08#2','2236U','2236L','TT08','2240P','2240M','2250P','2250M','2255B',
    #             '2260A','2270M','2280M','2290P','2290M','2300P','2300M','2310P','2310M','2315B',
    #             '2320P','2320A','2330P','2340M','2350P','2350A','2355P','2355B','2356U','2356L',
    #             'TT09','2360M','2370P','2370A','2375B','2380P','2390M','2410M','2420P','2420M',
    #             '2430M','2440M','2450M','2460P','2460M','2470P','2470M','2475P','2475A','2476U',
    #             '2476L','TT10','2480P','2480M','2490P','2490M','2500P','2500M','2505P','2505#1',
    #             '2505#2','2505B','2145#1','2145#2','2145#3','2145#4','2145#5','2145#6','2145#7',
    #             '2145#8','2145R']


##    stasFineAS = ['1010M','2490M','1430M-1','2010M','1250M','1260M','2130A-1','2130A-2',
##        '1008B','1020A','1030A','1035B',
##        '1050M','1055M','1060M','1070M','1080A','1090M',
##        '1100M','1110A','1115B','1120A',
##        '1140M','1150M','1160A','1170M','1180M',
##        '1190A','1220M','1230M',
##        '1240A','1265R','1270M',
##        '1280M','1300M','1261M','1275A','1290A','1310A','1315B',
##        '1320A','1330M','1340M','1350A-1','1350A-2','1355B','1360M',
##        '1370A','1380M','1390M','1400A-1','1400A-2',
##        '1405B','1410M','1420M','2010M',
##        '2020M','2030M','2055B','2060M','2070M','2080M',
##        '2090M','2110M','2120M',
##        '2140M','2170M','2180A','2190M',
##        '2230M','2360M','2390M','2400M',
##        '2410M','2460M','2470M',
##        '2480M','1210S1','2050A-1','2050A-2','2185B','2290M','2310M','2370M','2440M','2475A',
##        '1210S3','3010M','3020M','3030S1','3030S2','3040S','3050M','3060A1',
##        '3070A','3080A','3090A','3100A','3105R','3110A','3120M','2250M','2320M','2350A','2240M',
##        '2280M','2300M','2340M','2145R',
##        '1006R','1126R','1196R','1445R','1416R','2225R','2006R','2356R',
##        '2160A'
##        # ,'1266R','1366R','2236R','2196R','2476R''1096R',
##        ]
    stasFineAS  = [
        '1006R', '1008B', '1010M', '1020A', '1030A', '1035B', '1050M', '1055M', '1060M', '1070M',
        '1080A', '1090M', '1100M', '1110A', '1115B', '1120A', '1126R', '1140M', '1150M', '1160A',
        '1170M', '1180M', '1190A', '1196R', '1210S1', '1210S3', '1220M', '1230M', '1240A', '1250M',
        '1260M', '1261M', '1265R', '1270M', '1275A', '1280M', '1290A', '1300M', '1310A', '1315B',
        '1320A', '1330M', '1340M', '1350A-1', '1350A-2', '1355B', '1360M', '1370A', '1380M',
        '1390M', '1400A-1', '1400A-2', '1405B', '1410M', '1416R', '1420M', '1430M-1', '1445R',
        '2006R', '2010M', '2010M', '2020M', '2030M', '2050A-1', '2050A-2', '2055B', '2060M',
        '2070M', '2080M', '2090M', '2110M', '2120M', '2130A-1', '2130A-2', '2140M', '2145R',
        '2160A', '2170M', '2180A', '2185B', '2190M', '2225R', '2230M', '2240M', '2250M',
        '2280M', '2290M', '2300M', '2310M', '2320M', '2340M', '2350A', '2356R', '2360M',
        '2370M', '2390M', '2400M', '2410M', '2420M', '2430M', '2440M', '2460M', '2470M', '2475A', '2480M',
        '2490M', '3010M', '3020M', '3030S1', '3030S2', '3040S', '3050M', '3060A1', '3070A',
        '3080A', '3090A', '3100A', '3105R', '3110A', '3120M'
        ]



    # N12 = {'AZ','BW','SM'}
    # N12A = {'HA','CV','NG','NH','CE','CK','RZ'}
    # N15 = {'RA','CS'}
    # N15A = {'DF','RE','RC','RF','SA','SB','TB','UV','UW','UX','UY','UZ'}
    N12, N12A, N15, N15A = getEngineTypes()

    log = errorInformation()
    

    with multiprocessing.Manager():
        staStatus=multiprocessing.Manager().dict()
        shiftHour = multiprocessing.Manager().list()
        shiftHour.append(19)
        shiftHour[0] = shiftHourGet()
        shiftHour.append(shiftHour[0])
        

        errorProofingQueue = multiprocessing.Manager().Queue(100)
        keyParaQueue = multiprocessing.Manager().Queue(50)
        errorQueue = multiprocessing.Manager().Queue(50)
        staRecordQueue = multiprocessing.Manager().Queue(100)
        Q_LAYOUT_ANDON = multiprocessing.Manager().Queue(100)

        text = 'Current shift time is %s .'%(str(shiftHour[0]))
        errorQueue.put(['info',text])
        
        

        for stas in [stasR,stasB,stasP,stasPalletno]:
            initStaStatus(staStatus,stas)

        errorProcesses=[]
        for i in range(len(errorIDs)):
            if len(errorIDs[i]) != 0:
                errorProcesses.append(Process(
                    target=getErrorData,
                    args=(staStatus,ips[i],errorIDs[i],errorStations[i],errorQueue,shiftHour,errorProofingQueue,keyParaQueue)))

        processes=[]
        for i in range(len(stasR)):
            processes.append(Process(
                target=getStaData,
                args=(staStatus,stasR[i],ips[i],ns[i],stasB[i],stasP[i],stasPalletno[i],errorQueue,keyParaQueue,)))
        
        for errorProcess in errorProcesses:
            errorProcess.start()
            time.sleep(0.05)

        for process in processes:
            process.start()
            time.sleep(0.05)

        nnn=1
        stasRflatten=[sta for stas in stasR for sta in stas]
        stasPflatten=[sta for stas in stasP for sta in stas]
        lenStaRFla=len(stasRflatten)
        lastBuildable=[0]*lenStaRFla
        
        lastEUN = {}
        lastCount = {}
        lastPa = {}
        lastXXX = {}
        for sta in stasRflatten:
            lastEUN[sta] = ''
            lastCount[sta] = 0
            lastPa[sta] = 0
            lastXXX[sta] = ''

        LoopAFirst,LoopASecond,LoopBFirst,LoopBSecond = updateAsPerhourOut()

        staPresentRecordProc = Thread(
            target=layoutRecord,
            args=(staSequence,staStatus,)
            )
        staPresentRecordProc.start()
        print('staPresentRecordProc started!!!!!!!!!')

        getStaRecordTargetProc = Thread(
            target=getStaRecordTarget,
            args=(staRecordQueue,errorQueue,staStatus,stasRflatten,)
            )
        getStaRecordTargetProc.start()
        print('getStaRecordTargetProc started!!!!!!!!!')
        time.sleep(2)

        staRecordProc = Thread(
            target=staRecordP,
            args=(staRecordQueue,)
            )
        staRecordProc.start()
        print('staRecordProc started!!!!!!!!!')
        time.sleep(1)

        errorProofingRecordProc = Thread(
            target=errorProofingRecord,
            args=(errorProofingQueue,errorQueue,)
        )
        errorProofingRecordProc.start()
        print('errorProofingRecordProc started!!!!!!!!!')
        time.sleep(1)

        keyParaRecordProc = Thread(
            target=keyParaDataRecord,
            args=(keyParaQueue,)
        )
        keyParaRecordProc.start()
        print('keyParaRecordProc started!!!!!!!!!')
        time.sleep(1)

        andon_handle_thread = Thread(
            target=andon_handle,
            args=(staSequence, Q_LAYOUT_ANDON,)
            )
        andon_handle_thread.start()
        print('andon_handle_thread started!!!!!!!!!')
        time.sleep(1)



        shiftChangFlag = True

        lastCounts = [0,0]

        eunFlag = 0

        loopaCount = 0
        loopbCount = 0

        while 1:
            try:
                insertErrorproofingDefault()
            except:
                pass
            if errorQueue.qsize() > 0:
                for i in range(errorQueue.qsize()):
                    error = errorQueue.get()
                    if error[0] == 'info':
                        log.logInfo(error[1])
                    elif error[0] == 'err':
                        log.logError(error[1])

            nnn+=1

            if nnn % 5 == 1:
                curhour=int(datetime.datetime.now().strftime("%H"))
                if curhour in [8,shiftHour[0]] and shiftChangFlag:
                    loopaCount = 0
                    loopbCount = 0
                    # lastCounts = [[0,0,0],[0,0,0]]
                    shiftChangFlag = False
                elif curhour in [7,shiftHour[0]-1] and shiftChangFlag ==False:
                    shiftChangFlag = True
                
                loopaCountTmp = staStatus['1430M-1']['goodpiece']
                loopbCountTmp = staStatus['2490M']['goodpiece']
                
                if loopaCountTmp != 0:
                    if loopaCountTmp - lastCounts[0] > 0:
                        loopaCount += (loopaCountTmp - lastCounts[0])
                        lastCounts[0] = loopaCountTmp
                    elif loopaCountTmp - lastCounts[0] < 0:
                        loopaCount += loopaCountTmp
                        lastCounts[0] = loopaCountTmp
                    elif loopaCountTmp - lastCounts[0] == 0:
                        # loopaCount = loopaCountTmp
                        pass

                if loopbCountTmp != 0:
                    if loopbCountTmp - lastCounts[1] > 0:
                        loopbCount += (loopbCountTmp - lastCounts[1])
                        lastCounts[1] = loopbCountTmp
                    elif loopbCountTmp - lastCounts[1] < 0:
                        loopbCount += loopbCountTmp
                        lastCounts[1] = loopbCountTmp
                    elif loopbCountTmp - lastCounts[1] == 0:
                        # loopbCount = loopbCountTmp   
                        pass     


                print(nnn//15,' LOOPA:',loopaCount,'   LOOPB:',loopbCount)
                outut_perhourRecord(loopaCount,loopbCount,shiftHour[0])
                print(nnn//15,' LOOPA:',loopaCount,'   LOOPB:',loopbCount)

                
                if  curhour in [7,8,shiftHour[0]]:
                    for i in range(len(errorListVisible)):
                        ecode = staStatus[errorListVisible[i][1]]['EUN'][3:5]
                        if ecode in N12:
                            if 'N12' in errorListVisible[i][2]:
                                updateErrorListVisible(int(errorListVisible[i][0]),shiftHour)
                        elif ecode in N12A:
                            if 'N12A' in errorListVisible[i][2]:
                                updateErrorListVisible(int(errorListVisible[i][0]),shiftHour)
                        elif ecode in N15:
                            if 'N15' in errorListVisible[i][2]:
                                updateErrorListVisible(int(errorListVisible[i][0]),shiftHour)
                        elif ecode in N15A:
                            if 'N15A' in errorListVisible[i][2]:
                                updateErrorListVisible(int(errorListVisible[i][0]),shiftHour)

            if nnn % 6 == 1:
                try:
                    insertAsCount()
                    insertAsCountVertical()
                    for sta in stasFineAS:
##                        print('############',sta)
                        try:
                            updateFineAs(sta)
                        except Exception as e:
                            print(sta,e)
                    LoopAFirst,LoopASecond,LoopBFirst,LoopBSecond = updateAsPerhourOut()
                except Exception as e:
                    print('updateAsPerhourOut() error....',e)

            if nnn % 62  == 2:
                shiftHour[0] = shiftHourGet()
                if shiftHour[0] != shiftHour[1]:
                    text = 'Shift time had changed. Current shift time is %d .'%(shiftHour[0])
                    errorQueue.put(['info',text])
                    shiftHour[1] = shiftHour[0]

            time.sleep(1)


        staPresentRecordProc.join()
        staRecordProc.join()
        errorProofingRecordProc.join()
        keyParaRecordProc.join()
        
        for errorProcess in errorProcesses:
            errorProcess.join()
            
        for process in processes:
            process.join()

        
